Trying to access FirestoreAdminClient from Cloud Run service using firebase-admin. ERROR: 7 PERMISSION_DENIED: The caller does not have permission

Trying to access FirestoreAdminClient from Cloud Run service using firebase-admin. ERROR: 7 PERMISSION_DENIED: The caller does not have permission

我得到了 API 端点的以下代码,该端点应该使用 firebase-admin.

触发 Firestore 备份

这就是我初始化的方式 firebase-admin;

import * as admin from "firebase-admin";

admin.initializeApp({
  credential: admin.credential.cert(
    SERVICE_ACCOUNT as admin.ServiceAccount
)});

服务帐户密钥是 JSON 我使用默认 firebase-admin 服务帐户下载:

这是 backup.ts API 请求处理程序。

export const backupData: RequestHandler = async (req, res) => {
  try {

    const PROJECT_ID = process.env.PROJECT_ID;
    
    const client = new admin.firestore.v1.FirestoreAdminClient();
    const DB_NAME = client.databasePath(PROJECT_ID, "(default)");

    const BUCKET = `gs://${PROJECT_ID}.appspot.com`;
    const FOLDER = `firestore-backup`;
    const FULL_PATH = `${BUCKET}/${FOLDER}`;

    const responses = await client.exportDocuments({
      name: DB_NAME,
      outputUriPrefix: FULL_PATH,
      collectionIds: [] // CAN LIST SPECIFIC COLLECTIONS
    });

    const response = responses[0];
    return res.sendStatus(200);
  } else 
    return res.sendStatus(403);
  }
  catch(err) {
    console.error(err.message || DEFAULT_ERROR_MSG);
    return res.sendStatus(500);
  }
};

奇怪的是:

它在我的开发环境中完美运行。我的意思是,我 运行 我的本地服务器并点击 localhost:8080/api/backup(这是正确的端点)并且一切正常并且触发了备份。

但是在我将它部署到我的 cloud run 服务后,它就不再工作了。

这是我在云 运行 服务上遇到的错误:

7 PERMISSION_DENIED: The caller does not have permission

我是否需要向该服务帐户添加更多权限?但为什么它在我的本地开发环境中使用同一个服务帐户?在我的云 运行 服务上初始化服务帐户时,我不应该使用服务帐户吗?不知道在这里做什么。


更新 1:

我刚刚尝试像这样初始化它,但得到了相同的结果:

admin.initializeApp({
  credential: admin.credential.cert(SERVICE_ACCOUNT),
  databaseURL: `https://${PROJECT_ID}.firebaseio.com`,
  storageBucket: `${PROJECT_ID}.appspot.com`
});

此外,刚刚关注 this doc tutorial 并将这些角色添加到我的 firebase-adminPROJECT_ID@appspot.gserviceaccount.com。仍然无法正常工作:

更新 2:

this doc 之后,我刚刚尝试在没有任何参数的情况下初始化 firebase-admin。还是一样的结果:

admin.initializeApp();

更新 3:

根据之前的文档和 this doc,我已将 Cloud Datastore Import Export AdminStorage Admin 的 IAM 角色添加到我的 PROJECT_NUMBER-compute@developer.gserviceaccount.com 服务帐户。还是一样的结果。


结论

刚刚好。但是我已经做了很多尝试,所以我不太确定是什么让它起作用了。我猜这是我在 UPDATE 3 上所做的。明天会检查并回答。

我可以确认我在问题中描述的 UPDATE 3 成功了。因为我已经恢复了我在 UPDATE 1 and 2 上所做的更改并且它仍然工作正常。

似乎在我的本地环境中,firebase-admin 正在使用 firebase-adminsdk@PROJECT_ID.iam.gserviceaccount.com 服务帐户调用 FirestoreAdminClient API。我想这就是它起作用的原因。或者它可能正在使用我的 gcloud 登录帐户,即我的 owner 电子邮件。我不太确定。

但是一旦你在云 运行 环境中,即使 firebase-admin 是用同一个服务帐户初始化的,它似乎有点覆盖它并使用 xxxxxxxxx-compute@developer.gserviceaccount.com.这就是需要权限的人。

我从 Cloud Run Service Identity and Cloud Run IAM roles 那里得到了这个想法,它说:

我需要的角色来自:Firebase DOCS - Scheduled exports:

这是最终配置: