Firebase Functions调用enqueue()时出现服务账号识别失败错误
我写了一个简单的enqueue方法,用来给Firebase Functions队列添加任务:
async enqueue(args: UpdateCounterArgs): Promise<void> { const queue = getFunctions().taskQueue("updateCounter"); await queue.enqueue(args); }
我已经通过initializeApp()初始化了应用,之前使用的2个Realtime Database钩子和Firebase Storage都正常工作,因此初始化问题可以排除。
但在其他钩子中执行这个enqueue函数时,await queue.enqueue(args);这一行抛出如下错误:
Error: Failed to determine service account. Initialize the SDK with service account credentials or set service account ID as an app option.
我尝试将初始化的app传入getFunctions(app),但错误依旧。目前仅在本地通过Firebase模拟器进行测试。
完整示例代码:
import { onValueCreated } from "firebase-functions/v2/database"; import "reflect-metadata"; import { logger } from "firebase-functions/v1"; import { getFunctions } from "firebase-admin/functions"; import { initializeApp } from "firebase-admin/app"; initializeApp(); exports.test = onTaskDispatched((args) => { logger.log(args.data); }); exports.sendToTest = onValueCreated("test/{id}", async (event) => { const queue = getFunctions().taskQueue("updateCounter"); await queue.enqueue(event.data); });
在本地模拟器环境下使用Admin SDK调用任务队列,需要显式指定服务账号ID或提供凭证,可按以下方式处理:
显式设置服务账号ID
初始化Admin App时添加serviceAccountId配置项,使用Firebase项目默认的服务账号ID(格式通常为firebase-adminsdk-xxxx@[你的项目ID].iam.gserviceaccount.com),这个ID可以在Firebase控制台「设置」→「服务账号」页面找到:initializeApp({ serviceAccountId: "firebase-adminsdk-xxxx@your-project-id.iam.gserviceaccount.com" });通过环境变量自动获取配置
不想硬编码的话,可以利用Firebase CLI注入的环境变量自动构建服务账号ID:const firebaseConfig = JSON.parse(process.env.FIREBASE_CONFIG || "{}"); const projectId = firebaseConfig.projectId; initializeApp({ serviceAccountId: `firebase-adminsdk@${projectId}.iam.gserviceaccount.com` });检查模拟器运行状态
确保启动了Functions和任务队列模拟器,启动命令需包含对应的模拟器(比如firebase emulators:start --only functions,database),同时确认函数已正确连接到模拟器。
另外注意:示例代码中任务队列名称是updateCounter,但定义的任务处理函数是test,需保证队列名称和任务函数名称一致,否则也会出现异常。
内容的提问来源于stack exchange,提问作者ervin

