使用getFunctions部署Firebase Cloud Functions时出现SDK注解异常
问题:Firebase Cloud Functions部署报错"Unexpected annotation generated..."
我在index.ts文件中编写了两个Firebase Cloud Functions:一个用于处理任务队列,另一个是定时触发的任务入队函数,代码如下:
import functions from "firebase-functions"; import admin from "firebase-admin"; import * as fs from "fs"; import { getFunctions } from "firebase-admin/functions"; admin.initializeApp(); const db = admin.firestore(); const settings = {timestampsInSnapshots: true}; db.settings(settings); export const retireAtlistedEvents = functions .runWith( { memory: '2GB' }) .tasks.taskQueue({ retryConfig: { maxAttempts: 5, minBackoffSeconds: 60, }, rateLimits: { maxConcurrentDispatches: 6, }, }).onDispatch(async (data) => { const minEvent = data.minEvent as MinEventInfo; }) export const enqueueAtlistedEventsToRetire = functions .runWith( { memory: '2GB' }) .pubsub .schedule('0,15,30,45 * * * *').onRun(async context => { const queue = getFunctions().taskQueue("retireAtlistedEvents"); const enqueues = []; let minEvent: MinEventInfo = { proId: "abcd", eventId: "efgh" } enqueues.push( queue.enqueue({minEvent: minEvent}, { dispatchDeadlineSeconds: 20 // 20 seconds }), ); await Promise.all(enqueues) .then(() => { const exit: ExtendedExitMessage = { exit: 0, message: "enqueueAtlistedEventsToRetire success", success: true, }; return exit; }) .catch(() => { const exit: ExtendedExitMessage = { exit: 1, message: "enqueueAtlistedEventsToRetire success", success: false, }; return exit; }); });
执行部署命令 firebase deploy --only "functions:retireAtlistedEvents,functions:enqueueAtlistedEventsToRetire" 后,出现错误:
=== Deploying to 'my-project'... i deploying functions Running command: npm --prefix "$RESOURCE_DIR" run build > build > tsc ✔ functions: Finished running predeploy script. i functions: ensuring required API cloudfunctions.googleapis.com is enabled... i functions: ensuring required API cloudbuild.googleapis.com is enabled... ✔ functions: required API cloudbuild.googleapis.com is enabled ✔ functions: required API cloudfunctions.googleapis.com is enabled Error: Unexpected annotation generated by the Firebase Functions SDK. This should never happen.
我怀疑是代码中的 const queue = getFunctions().taskQueue("retireAtlistedEvents"); 这一行导致的,因为此前部署不含该代码的函数可以正常完成,想请教是否是getFunctions的导入方式存在问题?
解决方案
这个错误确实和你获取任务队列的方式有关。在同一个项目的Cloud Functions中引用本地定义的任务队列时,不需要通过firebase-admin的getFunctions()来获取,直接使用firebase-functions提供的functions.taskQueue()方法即可。
具体修改步骤:
- 删除从
firebase-admin/functions导入getFunctions的语句:import { getFunctions } from "firebase-admin/functions"; - 在入队函数中,将队列获取方式改为:
const queue = functions.taskQueue("retireAtlistedEvents");
修改后的完整代码:
import functions from "firebase-functions"; import admin from "firebase-admin"; // 如果fs模块未实际使用,可删除以下导入 import * as fs from "fs"; admin.initializeApp(); const db = admin.firestore(); const settings = {timestampsInSnapshots: true}; db.settings(settings); // 提前声明用到的类型,避免TypeScript编译错误 interface MinEventInfo { proId: string; eventId: string; } interface ExtendedExitMessage { exit: number; message: string; success: boolean; } export const retireAtlistedEvents = functions .runWith({ memory: '2GB' }) .tasks.taskQueue({ retryConfig: { maxAttempts: 5, minBackoffSeconds: 60, }, rateLimits: { maxConcurrentDispatches: 6, }, }).onDispatch(async (data) => { const minEvent = data.minEvent as MinEventInfo; // 补充你的任务处理逻辑 }); export const enqueueAtlistedEventsToRetire = functions .runWith({ memory: '2GB' }) .pubsub .schedule('0,15,30,45 * * * *').onRun(async context => { // 直接通过functions获取任务队列引用 const queue = functions.taskQueue("retireAtlistedEvents"); const enqueues = []; const minEvent: MinEventInfo = { proId: "abcd", eventId: "efgh" }; enqueues.push( queue.enqueue({minEvent: minEvent}, { dispatchDeadlineSeconds: 20 // 20 seconds }) ); // 改用try/catch替代Promise链式调用,代码更清晰 try { await Promise.all(enqueues); const exit: ExtendedExitMessage = { exit: 0, message: "enqueueAtlistedEventsToRetire success", success: true, }; return exit; } catch (err) { const exit: ExtendedExitMessage = { exit: 1, message: "enqueueAtlistedEventsToRetire failed", // 修正错误信息,避免混淆 success: false, }; return exit; } });
额外注意事项:
- 原代码中catch块的错误信息写为"success",建议修正为"failed",避免逻辑混淆
- 提前声明
MinEventInfo和ExtendedExitMessage接口,解决TypeScript编译时的类型未定义问题 - 如果
fs模块没有实际使用,可删除对应的导入语句,减少代码冗余
内容的提问来源于stack exchange,提问作者Willem Ghijsen
相关产品推荐
相关产品推荐

