Firebase Cloud Functions Firestore 触发器产生:错误:7 PERMISSION_DENIED:权限缺失或不足

Lar*_*s-B 13 firebase typescript google-cloud-functions google-cloud-firestore

当我的一个文档已使用触发器更新时,我正在尝试使用 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
Run Code Online (Sandbox Code Playgroud)

功能代码:

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;
  });
Run Code Online (Sandbox Code Playgroud)

包.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
}
Run Code Online (Sandbox Code Playgroud)

I assume that it has something to do with the permission of the admin instance, but no idea what the error could be, I've just followed the steps from the docs and the firebase videos on youtube.

My account is still on a Free Plan and I'm getting a notice in the logs the that I should configure the billing account, but if understand the documentation correct I should be able to access services within the Google Cloud Platform and so reading other nodes within the same database should not be a problem.

I've already found two similar issues here on stackoverflow, but did not find a solution there. Maybe someone else also faced this issue in the meantime and was able to solve it?

PERMISSION_DENIED Firestore CloudFunction TypeScript and Firebase error writing to Firestore via a Function: "7 PERMISSION_DENIED: Missing or insufficient permissions"

Update 1: Had another issue with the new timestampsInSnapshots setting. This has been fixed and the code above updated. The main issue permission denied is still present.

Update 2: Regarding the answer by @RonRoyston below. This is a Cloud Function and its using the Admin SDK from firebase-admin package to read the node. Hence it should not be effected by the firestore security rules. There's already a comment on one of the linked questions by @DougStevenson mentioning this. Based on the Admin SDK documentation it should be enough to initialize it by calling admin.initializeApp(), but unfortunately in my case it isn't. I've read no where that there is any need to apply any special IAM settings within the service accounts or security rules when using Cloud Functions, and so I didn't touch any of these settings.

Cheers, Lars

ADW*_*ADW 12

我遇到过同样的问题。和nvitius一样,我通过更改权限解决了这个问题。

创建函数时,默认服务帐户显示为<project-name>@appspot.gserviceaccount.com.

您可以通过单击Environment variables, networking, timeouts and more链接来检查这一点:

显示服务帐户

然后您可以验证帐户或将帐户更改为“App Engine 默认服务帐户”:

App Engine 默认服务帐号

之后,我前往 IAM 验证此服务帐户的权限。

但是 IAM 没有列出/添加此服务帐户。

所以我添加它 >> 添加 >> 新成员。开始输入项目的 ID,服务帐户应该会在下拉列表中弹出。

然后我给了它以下权限:

  • 项目 >> 编辑器(它可能已经有了)
  • 数据存储 >> 云数据存储所有者
  • 存储 >> 存储管理员

希望这可以帮助。


Mat*_*uel 11

我的解决方案是设置 serviceAccount,检查以下代码片段:

var admin = require("firebase-admin");

var serviceAccount = require("path/to/serviceAccountKey.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://your-database-url.firebaseio.com"
});
Run Code Online (Sandbox Code Playgroud)

您可以在以下位置生成 serviceAccountKey: Firebase 仪表板 -> 项目设置 -> 服务帐户选项卡

希望能帮助到你!


Lar*_*s-B 8

我终于让它工作了。我没有更改任何 Firestore 安全规则或任何 IAM 内容。我删除了 us-central1 上运行的函数。再次创建相同的 Cloud Function 项目,复制现有代码,但这次我将其部署到 europe-west1 并且它开箱即用。

我假设在第一次初始部署到 us-central1 期间可能会出现某些问题,之后即使我多次删除并重新部署该功能,我的项目仍会出现错误。不确定到底发生了什么,因为没有显示明显的错误。也许 Firebase 团队中了解内部工作流程的人可以告诉我们是否会发生类似的事情,如果会发生,如何处理。

目前,上述步骤解决了我的问题。

  • 我的上帝。遇到同样的错误。刚刚删除并重新部署了函数,即使使用默认的 us-central1 位置,它最终也能正常工作 (2认同)

nVi*_*ius 8

我在使用 Cloud Functions 时遇到了同样的问题。我的问题没有通过删除/重新部署功能解决。事实证明,在配置我的项目时,未添加默认服务帐户的 IAM 角色。我必须Editor在 IAM 管理面板中为<project-name>@appspot.gserviceaccount.com.