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

iOS应用Firebase云函数异步推送通知报错:Requested entity was not found

异步推送iOS静默通知时遇到「Requested entity was not found」错误

问题背景

现有一款接收推送通知的iOS应用,后端采用Node.js结合Firebase云函数实现。原有同步推送通知函数资源损耗过高,改成异步实现后出现报错,以下是测试静默通知的代码及错误日志。

测试代码

var allMesseges = []
const sendAllMessages = async () => {
  const sendMessege = allMesseges.map(async (message) => {
    let response = await admin.messaging().send(message);
  });
  await Promise.all(sendMessege);
};

exports.allSilentPushTrigerAsync = functions.database.ref('/development/allSilentPushTrigerAsync/').onWrite(async event => {
  let snap = await db.ref("users").once("value")
  let users = snap.val()
  for (const [key, user] of Object.entries(users)) {
    if (user.details.pushToken) {
      const message = {
        apns: {
          headers: {
            "apns-push-type": "background",
            "apns-priority": "5",
          },
          payload: {
            "aps": {
              "content-available": 1
            },
          },
        },
        token: user.details.pushToken,
      };
      allMesseges.push(message)
    }
  }
  await sendAllMessages()
})

错误日志

allSilentPushTrigerAsync
pzhv27hvepg4
Error: Requested entity was not found.
at Function.fromServerError (/workspace/node_modules/firebase-admin/lib/utils/error.js:254:16)
at createFirebaseError (/workspace/node_modules/firebase-admin/lib/messaging/messaging-errors-internal.js:35:47)
at /workspace/node_modules/firebase-admin/lib/messaging/messaging-api-request-internal.js:79:75
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async /workspace/index.js:180:28
at async Promise.all (index 4)
at async sendAllMessages (/workspace/index.js:182:9)
at async /workspace/index.js:207:10

at async /workspace/index.js:180:28 对应代码行:
let response = await admin.messaging().send(message);

at async /workspace/index.js:207:10 对应代码行:
await sendAllMessages()

问题分析

这个报错是FCM的典型错误,核心原因是推送token无效:

  • token已过期、被苹果APNs标记为无效(比如用户卸载App、设备重置、App更新后token未同步到后端)
  • token格式错误,或者不属于当前Firebase项目的有效推送token

另外你的代码还有几个潜在问题:

  1. 全局变量allMesseges(拼写错误,应为allMessages)在云函数实例复用场景下会导致消息累积,引发重复推送
  2. 没有错误处理,单个token推送失败会导致整个Promise.all中断,其他用户无法收到推送
  3. 循环调用send效率低下,FCM提供了更适合批量推送的sendMulticast方法

解决方案

1. 修复代码问题,改用批量推送

把全局变量移到函数内部,增加错误处理,用sendMulticast替代循环send:

exports.allSilentPushTrigerAsync = functions.database.ref('/development/allSilentPushTrigerAsync/').onWrite(async (event) => {
  const messages = [];
  const snap = await db.ref("users").once("value");
  const users = snap.val();

  // 收集有效推送消息
  for (const [key, user] of Object.entries(users)) {
    if (user.details?.pushToken) { // 用可选链避免属性不存在报错
      const message = {
        apns: {
          headers: {
            "apns-push-type": "background",
            "apns-priority": "5",
          },
          payload: {
            "aps": {
              "content-available": 1
            },
          },
        },
        token: user.details.pushToken,
      };
      messages.push(message);
    }
  }

  // 批量发送并处理结果
  if (messages.length > 0) {
    const response = await admin.messaging().sendMulticast({ messages });
    
    // 记录失败的推送,并收集无效token
    const invalidTokens = [];
    response.responses.forEach((resp, idx) => {
      if (!resp.success) {
        console.error(`推送失败,token: ${messages[idx].token},错误详情: ${resp.error.message}`);
        // 判断是否是token失效的错误
        if (resp.error.code === 'messaging/registration-token-not-registered') {
          invalidTokens.push(messages[idx].token);
        }
      }
    });

    // 可选:批量清理后端的无效token(根据你的数据结构调整)
    if (invalidTokens.length > 0) {
      const cleanTasks = invalidTokens.map(token => {
        return db.ref("users")
          .orderByChild('details/pushToken')
          .equalTo(token)
          .once('value')
          .then(snap => {
            snap.forEach(child => {
              child.ref.update({ 'details/pushToken': null });
            });
          });
      });
      await Promise.all(cleanTasks);
    }
  }
});

2. 日常维护建议

  • 每次App启动时,获取最新的推送token并同步到后端,覆盖旧token
  • 定期清理后端存储的无效token,减少无效推送请求
  • 推送时增加重试机制,针对临时错误(比如网络波动)可以重试1-2次

内容的提问来源于stack exchange,提问作者Миша Гарлинский

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 06:25:02