You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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()方法即可。

具体修改步骤:

  1. 删除从firebase-admin/functions导入getFunctions的语句:import { getFunctions } from "firebase-admin/functions";
  2. 在入队函数中,将队列获取方式改为:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:05:33