Firebase Cloud Functions Firestore トリガーが次のエラーを出力します: エラー: 7 PERMISSION_DENIED: 権限が不足しているか不十分です 質問する

Firebase Cloud Functions Firestore トリガーが次のエラーを出力します: エラー: 7 PERMISSION_DENIED: 権限が不足しているか不十分です 質問する

Firebase Cloud Function を使用して、Firestore データベース内のドキュメントを更新しようとしていますが、トリガーを使用してドキュメントの 1 つが更新されています。トリガーは呼び出され、正常に動作していますが、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;
  });

パッケージ.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 で 2 つの同様の問題を見つけましたが、そこでは解決策が見つかりませんでした。その間に他の誰かがこの問題に直面し、解決できたのでしょうか?

PERMISSION_DENIED Firestore CloudFunction TypeScriptそして関数経由で Firestore に書き込む際の Firebase エラー: 「7 PERMISSION_DENIED: 権限が不足しているか不十分です」

アップデート1:新しい timestampsInSnapshots 設定で別の問題が発生しました。この問題は修正され、上記のコードが更新されました。主な問題であるアクセス許可の拒否は依然として存在します。

アップデート2: 下記の@RonRoystonの回答について。これはクラウド関数であり、firebase-adminパッケージのAdmin SDKを使用してノードを読み取ります。したがって、Firestoreのセキュリティルールの影響を受けることはありません。すでにコメント@DougStevenson がリンクした質問の1つでこれについて言及しています。管理者 SDK ドキュメントadmin.initializeApp() を呼び出して初期化するだけで十分なはずですが、残念ながら私のケースではそうではありません。Cloud Functions を使用するときに、サービス アカウントまたはセキュリティ ルール内で特別な IAM 設定を適用する必要があると読んだことがなかったので、これらの設定には一切触れませんでした。

乾杯、ラース

ベストアンサー1

私も同じ問題を抱えていました。そしてエンビティウス権限を変更することで解決しました。

関数を作成すると、デフォルトのサービス アカウントは として表示されます<project-name>@appspot.gserviceaccount.com

リンクをクリックすると確認できますEnvironment variables, networking, timeouts and more:

サービスアカウントを表示するには

その後、アカウントを確認したり、アカウントを「App Engine のデフォルトのサービス アカウント」に変更したりできます。

App Engine のデフォルトのサービス アカウント

その後、IAM にアクセスして、このサービス アカウントに付与されている権限を確認しました。

しかし、IAM にはこのサービス アカウントがリスト/追加されていませんでした。

そこで、「追加 >> 追加 >> 新しいメンバー」と選択して追加します。プロジェクトの ID を入力し始めると、ドロップダウンにサービス アカウントが表示されます。

そして、次の権限を与えました。

  • プロジェクト >> エディター (すでにある可能性があります)
  • データストア >> クラウド データストアのオーナー
  • ストレージ >> ストレージ管理者

お役に立てれば。

おすすめ記事