Firebase云功能Firestore触发器产生:错误:7许可被拒绝:权限缺失或不足

b09cbbtk  于 2023-01-14  发布在  其他
关注(0)|答案(9)|浏览(146)

我尝试使用Firebase Cloud函数更新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云平台内的服务,因此阅读同一数据库内的其他节点应该不是问题。
我已经在stackoverflow上发现了两个类似的问题,但是没有找到解决方案。也许其他人也遇到了这个问题,并且能够解决它?
PERMISSION_DENIED Firestore CloudFunction TypeScriptFirebase error writing to Firestore via a Function: "7 PERMISSION_DENIED: Missing or insufficient permissions"

**更新1:**新的timestampsInSnapshots设置存在另一个问题。此问题已修复,并更新了上面的代码。主要问题权限被拒绝仍然存在。
更新2:关于下面@RonRoyston的回答。这是一个云函数,它使用firebase-admin包中的Admin SDK来读取节点。因此它不应该受到firestore安全规则的影响。@DougStevenson已经对其中一个链接问题发表了评论,提到了这一点。基于Admin SDK documentation,通过调用admin初始化它应该足够了。initializeApp(),但不幸的是,在我的情况下,它不是。我没有读到任何地方,有任何需要应用任何特殊的IAM设置的服务帐户或安全规则时,使用云功能,所以我没有接触任何这些设置。

干杯拉尔斯

xeufq47z

xeufq47z1#

我也遇到了同样的问题。和nvitius一样,我通过更改权限来解决它。
创建函数时,默认服务帐户显示为<project-name>@appspot.gserviceaccount.com
您可以通过单击Environment variables, networking, timeouts and more链接进行检查:

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

在此之后,我转到IAM以验证此服务帐户所具有的权限。
但IAM未列出/添加此服务帐户。
所以我添加它〉〉添加〉〉新成员。开始输入项目的ID,服务帐户应该在下拉菜单中弹出。
然后我给它以下权限:

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

希望这个有用。

scyqe7ek

scyqe7ek2#

我的解决方案是设置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"
});

您可以在以下位置生成serviceAccountKey:* Firebase控制面板-〉项目设置-〉服务帐户选项卡 *
希望能有所帮助!

qq24tv8q

qq24tv8q3#

我在云函数上遇到了同样的问题。我的问题没有通过删除/重新部署函数来解决。结果是,当我的项目被提供时,默认服务帐户的IAM角色没有被添加。我不得不在<project-name>@appspot.gserviceaccount.com的IAM管理面板中添加Editor角色。

aoyhnmkz

aoyhnmkz4#

我终于让它工作了。我没有改变任何firestore安全规则或任何IAM的东西。我删除了在us-central 1上运行的函数。再次创建了相同的Cloud Function项目,复制了我现有的代码,但这次我把它部署到europe-west 1上,它开箱即用。
我认为在第一次部署到us-central 1时可能出现了一些错误,之后我的项目一直出现错误,即使我删除并重新部署了几次函数。不确定到底发生了什么,因为没有显示明显的错误。也许firebase团队中了解内部工作流的人可以告诉我们是否会发生类似的事情,如果会,如何处理它。
目前,上述步骤解决了我的问题。

fdx2calv

fdx2calv5#

我遇到了同样的错误,并没有找到解决方案的任何地方,所以我张贴在这里,如果它可以帮助别人...
我们使用2个firebase项目(DEV,PROD),并在两个项目上部署相同的函数。当您在以下项目中指定错误的projectId时,也会出现PERMISSION_DENIED:

admin.initializeApp({projectId: 'your_project_id'});
zaqlnxep

zaqlnxep6#

一个解决方案对我很有效:

  • 我在firebase项目之间切换,我想模拟一个云函数,并在Firestore中查看生产结果(我已经让云函数在一个项目的生产Firestore中创建数据(例如“project-dev”)
  • 通过云功能在Firestore中创建新文档时,即使我使用了新项目的已下载serviceAccount凭据(“project-sandbox”),仍不断发生权限被拒绝错误
let serviceAccount = require('../credentials-sb.json');
admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://<project>-sandbox.firebaseio.com"
});
  • 我注意到我还没有为我的新项目运行firebase use命令,也没有将它添加到. firebaserc。我正在“使用”一个项目,而不是凭据文件所需要的项目(例如:Firebase CLI设置为使用“project-dev”,我还没有为新的“project-sandbox”运行firebase use命令)
  • 在我运行了firebase use project-sandbox之后,我运行了npm run shell并从模拟器执行了我的函数,一切都正常了。模拟器在“project-sandbox”中的工作就像在“project-dev”中一样。

我只能假设这是由于设置了一个project-id环境变量,该变量要么是在运行admin.initializeApp()时从环境中感应到的,要么是我可以像这样手动设置的(参见上面@Seb的注解):

let serviceAccount = require('../credentials-sb.json');
admin.initializeApp({
    project-id: '<project>-sandbox'
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://inkling-sandbox.firebaseio.com"
});

我希望这能有所帮助!如果有,请告诉我。

s8vozzvw

s8vozzvw7#

对我来说最简单的解决方案是运行以下命令:

firebase login //login through browser with project acc
firebase init firestore //When prompted select the firebase project

我在初始化项目的文件夹中运行了这个程序。

重要信息:每当询问是否覆盖时,选择“否”。
:这对我很有效,因为当我将项目从一台机器移到另一台机器时,我的本地函数突然停止工作。重新初始化项目对我很有帮助,而其他人都没有。

ctzwtxfj

ctzwtxfj8#

在我的例子中,我的服务帐户没有正确创建,所以我重新生成了服务帐户并重新部署它。

zxlwwiss

zxlwwiss9#

我能够用一个新的服务帐户干净地修复这个问题。

  1. IAM:创建新服务帐户
  2. IAM:将角色“云数据存储用户”和“Firebase规则查看器”分配给新服务帐户。
    1.云函数:编辑函数详细信息并为其设置新的服务帐户。

相关问题