【发布时间】:2019-01-21 20:18:47
【问题描述】:
当我的一个文档已使用触发器更新时,我正在尝试使用 Firebase 云函数来更新我的 Firestore 数据库中的文档。触发器被调用并且工作正常,但是当我使用 firebase 管理实例获取我想要更新的另一个文档时,我收到以下错误。
Error: 7 PERMISSION_DENIED: Missing or insufficient permissions.
at Object.exports.createStatusError (/user_code/node_modules/firebase-admin/node_modules/grpc/src/common.js:87:15)
at ClientReadableStream._emitStatusIfDone (/user_code/node_modules/firebase-admin/node_modules/grpc/src/client.js:235:26)
at ClientReadableStream._receiveStatus (/user_code/node_modules/firebase-admin/node_modules/grpc/src/client.js:213:8)
at Object.onReceiveStatus (/user_code/node_modules/firebase-admin/node_modules/grpc/src/client_interceptors.js:1256:15)
at InterceptingListener._callNext (/user_code/node_modules/firebase-admin/node_modules/grpc/src/client_interceptors.js:564:42)
at InterceptingListener.onReceiveStatus (/user_code/node_modules/firebase-admin/node_modules/grpc/src/client_interceptors.js:614:8)
at /user_code/node_modules/firebase-admin/node_modules/grpc/src/client_interceptors.js:1019:24
功能代码:
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
admin.initializeApp();
const settings = { timestampsInSnapshots: true };
admin.firestore().settings(settings);
export const onDocUpdate = functions.firestore
.document("documents/{documentId}")
.onUpdate((snapshot, context) => {
console.log("onDocUpdate called ", context.params.documentId);
const document = snapshot.after.data();
console.log("Document: ", document);
if (document.screw) {
console.log("Document screw exists. ", document.screw);
const docRef = admin
.firestore()
.collection("screws")
.doc(document.screw);
return docRef
.get()
.then(doc => {
if (doc.exists) {
console.log("Screw for document exists.");
} else {
console.error(
"Screw for document not found! ",
document.screw
);
}
})
.catch(error => {
// Here I get the permission error :(
console.error(
"Screw for document doc load error!! ",
error
);
});
} else {
console.error("Document is not bound to a screw! ", document.id);
}
return null;
});
package.json
{
"name": "functions",
"scripts": {
"lint": "tslint --project tsconfig.json",
"build": "tsc",
"serve": "npm run build && firebase serve --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"main": "lib/index.js",
"dependencies": {
"@google-cloud/firestore": "^0.16.0",
"firebase-admin": "^6.0.0",
"firebase-functions": "^2.0.4",
"protobufjs": "^6.8.8"
},
"devDependencies": {
"tslint": "~5.8.0",
"typescript": "~2.8.3"
},
"private": true
}
我认为这与管理员实例的权限有关,但不知道错误可能是什么,我只是按照 youtube 上的文档和 firebase 视频中的步骤进行操作。
我的帐户仍处于免费计划中,并且我在日志中收到一条通知,我应该配置结算帐户,但如果正确理解文档,我应该能够访问 Google Cloud Platform 中的服务等读取同一数据库中的其他节点应该不是问题。
我已经在 stackoverflow 上发现了两个类似的问题,但没有找到解决方案。也许其他人同时也遇到了这个问题并且能够解决它?
PERMISSION_DENIED Firestore CloudFunction TypeScript 和 Firebase error writing to Firestore via a Function: "7 PERMISSION_DENIED: Missing or insufficient permissions"
更新 1: 新的 timestampsInSnapshots 设置存在另一个问题。这已得到修复,上面的代码已更新。主要问题权限被拒绝仍然存在。
更新 2:关于下面@RonRoyston 的回答。这是一个云函数,它使用 firebase-admin 包中的 Admin SDK 来读取节点。因此,它不应受 Firestore 安全规则的影响。在@DougStevenson 提到的一个链接问题上已经有一个comment。基于Admin SDK documentation,通过调用 admin.initializeApp() 来初始化它应该足够了,但不幸的是在我的情况下它不是。我没有读到在使用 Cloud Functions 时需要在服务帐户或安全规则中应用任何特殊 IAM 设置的地方,因此我没有触及任何这些设置。
干杯, 拉尔斯
【问题讨论】:
-
您的 Firestore 规则不允许读取或写入。查看您的
firestore.rules文件。 -
@RonRoyston 感谢您的回复,但这是一个使用 firebase-admin 的云功能,它不应受 Firestore 安全规则的影响。请参阅我在问题中的完整答案(更新 2)。它还包含@DougStevenson 提到的链接。
-
在我使用 firebase serve --only 函数的情况下,我可以读取 firestore 集合。但是,在将 firebase 功能部署到云时,我会收到权限错误。这让我相信每个谈论 Firestore 规则的人都会让每个使用 admin.firestore() 的人走上死胡同。
标签: typescript firebase google-cloud-firestore google-cloud-functions