Pesquisa de site

typescript - Erro do Firebase ao escrever no Firestore via uma Função: "7 PERMISSION_DENIED: Permissões ausentes ou insuficientes"


Estou tentando escrever uma função simples do Firebase que adiciona um registro ao Firestore com TypeScript. A versão resumida do código é:

import * as admin from "firebase-admin";
import * as functions from "firebase-functions";

const config = functions.config();

admin.initializeApp(functions.config().firebase);
admin.database.enableLogging(true);

exports.subscriptions = functions.https.onRequest(
  async (req, res) => {
    try {
      const requestSubscription = req.body;
      const subscription = {
        subscription_id: requestSubscription.subscription_id,
        email: requestSubscription.email || ""
      };

      const id = subscription.subscription_id;
      const dbSubscriptions = admin.firestore().collection("subscriptions");
      await dbSubscriptions.doc(id).set(subscription);

      return res.status(200).send(`Success`);
    } catch (e) {
      console.error(e.stack);
      return res.status(500).send(`Error`);
    }
  }
);

Isso funciona como esperado localmente. Quando eu faço o deploy, recebo este erro:

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 Object.onReceiveStatus (/user_code/node_modules/firebase-admin/node_modules/grpc/src/client_interceptors.js:1214:28)
    at InterceptingListener._callNext (/user_code/node_modules/firebase-admin/node_modules/grpc/src/client_interceptors.js:590:42)
    at InterceptingListener.onReceiveStatus (/user_code/node_modules/firebase-admin/node_modules/grpc/src/client_interceptors.js:640:8)
    at callback (/user_code/node_modules/firebase-admin/node_modules/grpc/src/client_interceptors.js:867:24)

O arquivo functions/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": {
    "express": "4.16.3",
    "firebase-admin": "5.12.1",
    "firebase-functions": "1.0.3"
  },
  "devDependencies": {
    "tslint": "^5.8.0",
    "typescript": "^2.5.3"
  },
  "private": true
}

O único link que estou encontrando ao pesquisar por esse erro é esta pergunta não respondida: PERMISSION_DENIED Firestore CloudFunction TypeScript

Eu configurei minhas regras do Firestore para permitir que qualquer pessoa leia e escreva também, mesmo que o acima esteja usando o admin e ainda assim não funciona.

Alguém pode ajudar?

Resposta #1

Eu encontrei esse problema enquanto atualizava meu valor de conta IAM/Serviço e acho que descobri o que fazer.

Se você usar o Firebase Admin SDK sem fornecer nenhuma credencial nas Funções Firebase assim firebaseAdmin.initializeApp(), então suas funções usarão as credenciais padrão do aplicativo.

As credenciais padrão usam a seguinte conta de serviço {project-id}@appspot.gserviceaccount.com onde {project-id} será o ID do seu projeto do Firebase/Google Cloud. Essa conta é frequentemente criada automaticamente quando você cria um projeto no Firebase ou utiliza alguns dos serviços do Google Cloud.

De qualquer forma, {project-id}@appspot.gserviceaccount.com por padrão tem permissão de nível Editor. Você pode verificar isso na página [Google Cloud - IAM & Admin - IAM]. Eu achei que tinha permissões demais, então basicamente removi essa permissão da conta de serviço e decidi adicionar manualmente permissões mais restritivas. (Naquela época, eu não sabia que o Firebase/funções do Cloud usam essa conta de serviço).

Após fazer essas alterações, minhas funções que acessam o Firestore logo começaram a encontrar erros Error: 7 PERMISSION_DENIED: Missing or insufficient permissions.. Para resolver esse problema, tive que fazer as seguintes 2 coisas.

  • Adicionada novamente a permissão de nível Editor à conta de serviço padrão.
  • Excluiu completamente as funções do Firestore usando o console do Firebase e as reimplantou usando o comando firebase deploy --only functions.

Após completar os 2 passos acima, minhas funções na nuvem começaram a funcionar corretamente como esperado.

Resposta #2

Eu entrei em contato com o suporte do Firebase sobre isso e eles também não sabiam o que estava acontecendo. Eu criei um novo projeto, implementei e funcionou. Talvez seja apenas um bug estranho com projetos novos.

Artigos relacionados