繁体   English   中英

在我的 Next.js 应用程序中使用 getServerSideProps 时,Firebase 抛出权限不足

[英]Firebase throws insufficient permissions when using getServerSideProps in my Next.js app

我正在尝试创建一个聊天应用程序。 当用户前往 url www.myproject.com/chat/[id] ,它将获取对话数据。

我的安全规则很好,但是将规则更改为完全打开( allow read, write; )解决了问题。 所以这意味着在尝试获取数据时,当前用户auth状态必须为空(即使用户已登录)。

这是我的 [conversationid].tsx:

import React from "react";
import Head from "next/head";
import Navbar from "../../components/Navbar/Navbar";
import Footer from "../../components/Footer/Footer";
import Chat from "../../components/Chat/Chat";
import { getConversationData } from "../../services/firebase";

export async function getServerSideProps(context) {
  const response = await getConversationData(context.params.conversationid);
  if (response.success) {
    return {
      props: {
        conversationData: response.conversation,
      },
    };
  } else {
    return {
      notFound: true,
    };
  }
}

function Page({ conversationData }) {
  return (
    <>
      <Head>
        <title>Chat</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <Navbar page={"Profile"} />
      <Chat conversation={conversationData} />
      <Footer />
    </>
  );
}

export default Page;

获取对话数据的服务函数如下所示:

export async function getConversationData(conversationID: string) {
  const db = getFirestore(firebaseApp);
  const conversationDoc = doc(db, "conversations", conversationID);
  const response = await getDoc(conversationDoc);
  if (response.exists) {
    return {
      success: true,
      conversation: response.data(),
    };
  } else {
    return {
      success: false,
      conversation: null,
    };
  }
}

我对 NEXT 还是个新手,在加载页面之前处理这种从服务器获取数据的工作流程对我来说是陌生的,我最近刚刚学习了 React。 在这些应用程序中,处理auth状态以前对我来说不是问题。

我猜我必须等到auth状态可用? 或者cookies是可以使用的东西吗? 不确定处理此问题的常用方法。

这是我的安全规则。 有问题的是 /conversation/{conversationID} 和它下面的 {message} 规则:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /listings/{listingID} {
      allow read;
      allow update: if request.auth != null;
      allow write: if request.auth != null && request.auth.uid == resource.data.seller
      allow create: if request.auth != null;
    }
        match /listings/{listingID}/comments/{comment} {
      allow read; 
      allow write, create: if request.auth != null;
    }
    match /listings/{listingID}/comments/{comment}/replies/{reply} {
      allow read; 
      allow write, create: if request.auth != null;
    }
    match /users/{userID} {
      allow read;
      allow update: if (request.resource.data.diff(resource.data).affectedKeys()
        .hasOnly(['notifications'])) && request.auth != null;
      allow write: if request.auth != null && request.auth.uid == userID;
      allow create: if request.auth != null;
    }
    match /users/{userID}/notifications/{notification} {
      allow read, write: if request.auth != null;
    }
    match /users/{userID}/purchases/{purchase} {
      allow read, write: if request.auth.uid == userID || resource.data.sellerID == request.auth.uid;
    }
    match /users/{userID}/sold/{sold} {
      allow read, write: if request.auth.uid == userID || resource.data.buyerID == request.auth.uid;
    }
    match /tradeOffers/{tradeOfferID} {
      allow read;
      allow write: if request.auth.uid == resource.data.receiverID || request.auth.uid == resource.data.senderID;
      allow create: if request.auth != null;
    }
    match /trades/{tradeID} {
          allow read;
      allow write: if request.auth.uid == resource.data.receiverID || request.auth.uid == resource.data.senderID;
      allow create: if request.auth != null;
    }
    match /trades/{tradeID}/messages/{message} {
      allow read, create: if request.auth != null;
    }
    match /keywords/{keywordID} {
      allow read;
      allow create;
      allow update: if request.resource.data.hits == (resource.data.hits + 1);
    }
    match /medals/{medal} {
        allow read;
    }
    match /alphaFeedback/{alphaFeedbackID} {
        allow write: if request.auth.uid != null;
    }
    match /reports/{reportID} {
        allow write: if request.auth.uid != null;
    }
    match /conversations/{conversationID} {
        allow read, write: if request.auth != null;
    }
    match /conversations/{conversationID}/messages/{messageID} {
        allow read, write: if request.auth != null;
    }
  }
}

这是我在尝试加载对话时遇到的错误的屏幕截图:

在此处输入图片说明

这是错误代码:

    error - Error [FirebaseError]: Missing or insufficient permissions.
    at new FirestoreError (/Users/lewis/Desktop/www.hoardboard.co.uk/node_modules/@firebase/firestore/dist/index.node.cjs.js:410:28)
    at fromRpcStatus (/Users/lewis/Desktop/www.hoardboard.co.uk/node_modules/@firebase/firestore/dist/index.node.cjs.js:7519:12)
    at fromWatchChange (/Users/lewis/Desktop/www.hoardboard.co.uk/node_modules/@firebase/firestore/dist/index.node.cjs.js:7734:35)
    at PersistentListenStream.onMessage (/Users/lewis/Desktop/www.hoardboard.co.uk/node_modules/@firebase/firestore/dist/index.node.cjs.js:15639:27)
    at /Users/lewis/Desktop/www.hoardboard.co.uk/node_modules/@firebase/firestore/dist/index.node.cjs.js:15572:30
    at /Users/lewis/Desktop/www.hoardboard.co.uk/node_modules/@firebase/firestore/dist/index.node.cjs.js:15608:28
    at /Users/lewis/Desktop/www.hoardboard.co.uk/node_modules/@firebase/firestore/dist/index.node.cjs.js:21975:13
    at /Users/lewis/Desktop/www.hoardboard.co.uk/node_modules/@firebase/firestore/dist/index.node.cjs.js:22041:20
    at processTicksAndRejections (internal/process/task_queues.js:95:5) {
  code: 'permission-denied',
  toString: [Function (anonymous)],
  page: '/chat/[conversationid]'

我相信它与 getServerSideProps 的属性有关,它会使用 getServerSideProps 返回的数据在每个请求上预渲染页面。 因此,在发出请求时,不会加载 firebase 用于检查您是否确实已登录所需的令牌。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM