我使用 firebase 模拟器(auth、firestore 和 firebase 功能)进行本地主机部署。
我有一个表单尝试写入数据库并收到
FirebaseError: Missing or insufficient permissions.
通常我认为这是典型的 firestore.rules
问题。于是我进一步检查,没有发现任何配置错误。因此,为了确认我将其注释掉以使用默认测试部署规则来允许读/写所有文档。 (我知道这很糟糕,但这是一次健全性检查)。我仍然有同样的错误。我很困惑是什么导致了这种情况发生。
控制台显示保存到我的 firestore.rules 文件后已应用更改。所以我可以排除模拟器无法正确加载文件的情况。
这是产生的代码和错误。当用户想要提交提案时,数据将写入数据库。对于这个例子,我执行了读取和写入。
// React modal which attempts to access the firestore db
import React, { useRef } from "react";
import { collection, getDocs, addDoc, Timestamp } from "firebase/firestore";
import { db, getCurrentUser } from "../services/Firebase";
const ProposalModal = ({
showModal,
toggleWindow,
userAddress,
tokenid,
...props
}) => {
const referenceDescriptionTextArea = useRef();
const proposalsCollectionReference = collection(db, "proposals");
const handleProposalSubmit = async (event) => {
console.log("handleProposalSubmit");
event.preventDefault();
var data = {
author: getCurrentUser().uid,
timestamp: Timestamp.now(),
tokenid: tokenid,
type: "frenbio",
description: referenceDescriptionTextArea.current.value,
};
console.log("STORING: " + data);
getDocs(proposalsCollectionReference).then( //errors
(snapshot) => {
console.log(snapshot.docs);
},
(err) => {
console.log(err);
}
);
console.log("READING");
addDoc(proposalsCollectionReference, data).then( //errors
(docRef) => {
console.log(docRef.id); //p4eZcO5QV43IYnigxALJ
toggleWindow();
},
(err) => {
console.log(err);
}
);
};
return( //some component render for the modal)
};
我的 Firestore 规则: 最初,我创建了提案规则,只允许经过身份验证的用户进行写入。客人可以自由阅读提案。
request.auth != null
看起来还可以。我让用户使用signInWithCustomToken 方法进行身份验证,该方法非常适合我的应用程序。我使用 getCurrentUser
引用用户的身份验证对象。在提案失败后,我打开了所有文档的读写功能,但错误仍然存在。
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Commented out as R/W was not working
// match /proposals/{doc} {
// allow read: if true;
// allow write: request.auth != null;
// }
match /{document=**} {
allow read, write: if true; //Note: Giving full rights still fail
}
}
}
我的方法是否对 firestorerules、调用本身或其他内容不正确?
**编辑:** Firebase 工具版本为 11.9.0。 这是完整的包装清单
{
"name": "functions",
"scripts": {
"lint": "eslint --ext .js,.ts .",
"build": "tsc",
"build:watch": "tsc --watch",
"serve": "npm run build && firebase emulators:start --only functions",
"serve-all": "npm run build && firebase emulators:start",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "16"
},
"main": "lib/index.js",
"dependencies": {
"@metamask/eth-sig-util": "^4.0.0",
"firebase-admin": "^10.0.2",
"firebase-functions": "^3.18.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.12.0",
"@typescript-eslint/parser": "^5.12.0",
"eslint": "^8.9.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-import": "^2.25.4",
"firebase-functions-test": "^0.2.0",
"typescript": "^4.5.4"
},
"private": true
}
您必须保留在初始规则集中给定的 /databases/{database}/documents 的匹配,以对用户进行身份验证,如文档中所示。请尝试对安全规则进行以下更改。当您使用对文档的混合公共和私人访问时,请查看有关配置详细信息的有用文档。
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
您还可以查看此教程,以这种方式配置 firestore Web 客户端:
const db = firebaseApp.firestore();
if (window.location.hostname === "localhost") { console.log("localhost detected!");
db.settings({ host: "localhost:8080", ssl: false }); }
规则游乐场是一个方便的工具,可以在您探索新行为或在编写规则时快速验证规则时使用。它会显示一条消息,确认根据您为模拟设置的参数允许或拒绝访问。您可以在此处找到 [规则游乐场] 的文档6,但您所需要做的就是插入您想要读/写的路径的模拟位置。
在此处查看类似的实施示例
connectFirestoreEmulator(db, 'localhost', 8080);
。显然仅在开发期间