javascript - 在我的 Next.js 应用程序中使用 getServerSideProps 时,Firebase 引发的权限不足
问题描述
我正在尝试创建一个聊天应用程序。当用户前往该网址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 检查您是否确实已登录所需的令牌在发出请求时不会被加载。
推荐阅读
- java - 使用 @KafkaListener 对 Kafka 消费者进行勇敢的跟踪
- python - 我收到了一个文件未找到错误和名称错误,尽管该文件位于同一目录中
- javascript - 我们如何将伪类添加到 SVG 路径
- java - JTable 窗口不显示 ArrayList 内容
- java - 数据报包问题。一条成功消息后,包长度更改为 15 个字节。(UDP, JAVA)
- angular - Angular 10 mat-table onClick 滚动到表格顶部
- amazon-web-services - 如何从 cli 指定 EC2 实例类型?
- spring - Spring 安全提供者优先级
- c++ - 将向量的向量复制到一维数组中
- c# - 如何在 Windows 10 的 WinForms 中禁用触摸滚动?