Администратор Firestore в Node.js Отсутствует или недостаточно прав - PullRequest
0 голосов
/ 06 сентября 2018

Я пытаюсь получить доступ к Firestore, используя Firebase Admin на Node.js v8.4.0 в облачной функции Firebase, работающей локально с использованием функций firebase: оболочка в Windows 10.

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 Permission Denied.

Обновление 2: Установите учетные данные приложения по умолчанию, используя gcloud auth application-default login в соответствии с предложением @Doug Stevenson. Гарантированная переменная среды GOOGLE_APPLICATION_CREDENTIALS не установлена. Попытка кода в 1,2 и 3 выше, а также 4 ниже безуспешно. Обнаружена та же ошибка.

4

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

1 Ответ

0 голосов
/ 09 января 2019

Я надеюсь, что к настоящему времени вы уже решили свою проблему. То же самое случилось со мной, и я делюсь тем, что было в моем случае, с надеждой, что это поможет другим.

Мы управляем несколькими проектами 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, он заработал для меня.

...