Node.js 中的 Firestore 管理员权限缺失或不足

Posted

技术标签:

【中文标题】Node.js 中的 Firestore 管理员权限缺失或不足【英文标题】:Firestore admin in Node.js Missing or insufficient permissions 【发布时间】:2019-02-11 21:34:58 【问题描述】:

我正在尝试在 Node.js v8.4.0 上使用 Firebase Admin 访问 Firestore,在 Firebase Cloud Function 中使用 Firebase 函数在本地运行:Windows 10 上的 shell。

firebase -v 4.2.1

  "dependencies": 
    "firebase-admin": "^6.0.0",
    "firebase-functions": "^2.0.5"
  

尝试从我的应用程序代码中使用 firebase admin 后,我尝试运行 https://github.com/firebase/functions-samples/blob/master/quickstarts/uppercase-firestore/functions/index.js 中的快速入门示例。

这是实际运行的代码:

'use strict';

// [START all]
// [START import]
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');

// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');

admin.initializeApp()
// [END import]

// [START addMessage]
// Take the text parameter passed to this HTTP endpoint and insert it into the
// Realtime Database under the path /messages/:documentId/original
// [START addMessageTrigger]
exports.addMessage = functions.https.onRequest((req, res) => 
// [END addMessageTrigger]
  // Grab the text parameter.
  const original = req.query.text;
  // [START adminSdkAdd]
  // Push the new message into the Realtime Database using the Firebase Admin SDK.
  return admin.firestore().collection('messages').add(original: original).then((writeResult) => 
    // Send back a message that we've succesfully written the message
    return res.json(result: `Message with ID: $writeResult.id added.`);
  );
  // [END adminSdkAdd]
);
// [END addMessage]

// [START makeUppercase]
// Listens for new messages added to /messages/:documentId/original and creates an
// uppercase version of the message to /messages/:documentId/uppercase
// [START makeUppercaseTrigger]
exports.makeUppercase = functions.firestore.document('/messages/documentId')
    .onCreate((snap, context) => 
// [END makeUppercaseTrigger]
      // [START makeUppercaseBody]
      // Grab the current value of what was written to the Realtime Database.
      const original = snap.data().original;
      console.log('Uppercasing', context.params.documentId, original);
      const uppercase = original.toUpperCase();
      // You must return a Promise when performing asynchronous tasks inside a Functions such as
      // writing to the Firebase Realtime Database.
      // Setting an 'uppercase' sibling in the Realtime Database returns a Promise.
      return snap.ref.set(uppercase, merge: true);
      // [END makeUppercaseBody]
    );
// [END makeUppercase]
// [END all]

但是,我仍然收到权限被拒绝错误。

这是我得到的输出:

firebase > makeUppercase(original:'alphabets',params:documentId:'mydoc')
'Successfully invoked function.'
firebase > info: User function triggered, starting execution
info: Uppercasing mydoc alphabets
info: Function crashed
info:  Error: 7 PERMISSION_DENIED: Missing or insufficient permissions.
    at Object.exports.createStatusError (C:\projects\myproject\functions\node_modules\grpc\src\common.js:87:15)
    at Object.onReceiveStatus (C:\projects\myproject\functions\node_modules\grpc\src\client_interceptors.js:1188:28)
    at InterceptingListener._callNext (C:\projects\myproject\functions\node_modules\grpc\src\client_interceptors.js:564:42)
    at InterceptingListener.onReceiveStatus (C:\projects\myproject\functions\node_modules\grpc\src\client_interceptors.js:614:8)
    at callback (C:\projects\myproject\functions\node_modules\grpc\src\client_interceptors.js:841:24)
  code: 7,
  metadata: Metadata  _internal_repr:  ,
  details: 'Missing or insufficient permissions.' 

我的安全规则是完全开放的,但这并没有解决错误。

service cloud.firestore 
  match /databases/database/documents 
    match /document=** 
      allow read, write;
    
  

我还认为这可能是身份验证问题,所以我尝试了以下方法来初始化应用程序:

1

admin.initializeApp()

2

admin.initializeApp(functions.config().firebase);

3

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

admin.initializeApp(
  credential: admin.credential.cert(serviceAccount),
  databaseURL: 'https://<DATABASE_NAME>.firebaseio.com'
);

最后一个带有我自己的凭据文件和项目配置。所有这些尝试仍然给我缺少权限错误。

更新: 我将这些功能部署到云端,它们似乎运行良好,但在本地运行时,我仍然收到错误:7 权限被拒绝。

更新 2: 根据@Doug Stevenson 的建议,使用gcloud auth application-default login 设置应用程序默认凭据。确保未设置环境变量 GOOGLE_APPLICATION_CREDENTIALS。尝试了上面 1,2 和 3 以及下面 4 中的代码,但没有成功。遇到了同样的错误。

4

admin.initializeApp(
    credential: admin.credential.applicationDefault(), 
    databaseURL: "https://myapp-redacted.firebaseio.com"
  );

【问题讨论】:

如果你尝试正常部署和调用函数(不使用模拟器)会发生什么? 实际部署按预期工作。该错误仅在仿真期间发生。 您能否编辑问题以显示无法按您期望的方式工作的确切代码? (不要只是链接到它 - 显示您的实际代码) 用实际代码运行更新了问题。确保存在“消息”集合。 您是否碰巧安装了 gcloud 或使用其他云服务? 【参考方案1】:

我希望您现在已经解决了您的问题。同样的事情也发生在我身上,我正在分享我的情况,希望它能帮助其他人。

我们管理多个 firebase 项目 - 制作、开发、登台等。

我们用这个来初始化 admin sdk:

let serviceAccount = require("../serviceAccountKey.json");
const databaseUrl = functions.config().environment.databaseurl
const storageBucket = functions.config().environment.storagebucket
const isDev = "true" === functions.config().environment.dev

// if dev environment
if (isDev) 
  serviceAccount = require("../serviceAccountKey-dev.json");


admin.initializeApp(
    projectId: functions.config().environment.projectid,
    credential:    admin.credential.cert(serviceAccount),
    databaseURL:   databaseUrl,
    storageBucket: storageBucket
);

你知道你需要做什么

firebase functions:config:get > .runtimeconfig.json

为了模拟工作。好吧,我的 runtimeconfig 包含错误的配置。我正在加载我的 serviceAccountKey-dev,但我试图访问另一个项目。第二个我修复了我的 runtimeconfig - 它对我有用。

【讨论】:

【参考方案2】:

最终我只需要运行gcloud auth application-default login 以确保我使用正确的 Google 帐户登录。

【讨论】:

【参考方案3】:

我遇到了同样的问题,通过转到the cloud console 然后将角色Firebase Admin SDK admin service agent 授予应用引擎服务帐户,该帐户采用以下格式PROJECT_ID@appspot.gserviceaccount.com 得到了解决。

【讨论】:

以上是关于Node.js 中的 Firestore 管理员权限缺失或不足的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 云功能“get() 中的 firestore set() 如果不存在”无法正常工作?

如何从 Cloud Firestore 数据库中获取 node.js 中的特定字段值?

将 Firestore 依赖项和类型导入 node.js

尝试将谷歌云功能与 node.js 一起使用时,admin.firestore 不是一个功能

使用 node.js 标准环境在 AppEngine 上找不到模块 @google-cloud/firestore

基于Node.js开发个性化全网内容抓取平台