如何通过Firebase Admin SDK利用FCM批量推送大量通知?
核心问题解答
当你调用fcm.sendToDevice批量发送时,单个失效令牌不会导致整批请求失败。FCM会分别处理每个令牌:
- 有效令牌对应的设备会正常收到通知;
- 失效/无效的令牌(比如已卸载应用、令牌过期)会在返回的响应结果中标记错误状态(如
NotRegistered、InvalidRegistration),但不会影响同批次其他令牌的发送。
只有当整个请求出现全局错误(比如权限不足、请求格式完全错误)时,才会导致整批调用抛出异常。
遗漏的注意事项
- 处理无效令牌:每次批量发送后,要解析FCM返回的响应,提取出标记为失败的令牌,从Firestore的User集合中删除这些无效令牌,避免后续重复发送浪费资源。
- 添加错误捕获:当前代码中,如果某一批次的
sendToDevice触发全局异常(比如临时网络故障),Promise.all会直接终止所有后续执行。建议给每个批次的调用包裹try/catch,确保单个批次的失败不会影响其他批次:const sendInChunks = chunkedList.map(async (tokenArr) => { try { const response = await fcm.sendToDevice(tokenArr, message); // 这里处理响应中的失败令牌 } catch (err) { console.error(`发送批次失败: ${err}`); } }); - 控制并发请求数:直接用
map发起所有批次的并发请求,可能触发FCM的速率限制。建议使用并发控制工具(如p-limit)限制同时发送的批次数量,避免被限流。 - 检查消息格式:你的代码中
message是字符串,但sendToDevice要求传入的是符合FCM规范的消息对象,比如:
传入字符串会导致发送失败。const message = { notification: { title: "通知标题", body: "some message" }, // 可选:数据负载 data: { key: "value" } }; - 避免一次性拉取所有用户:如果User集合文档量很大,一次性获取所有文档会占用大量内存,还可能触发Firestore的读取限制,甚至导致Functions超时。建议用分页查询(
startAfter)分批获取用户数据。 - 关注Functions超时限制:Firebase计划函数的默认超时时间是9分钟,若用户量极大,批量发送耗时可能超过这个限制,需要调整函数的超时配置,或者拆分任务为多个小任务。
- 日志与监控:记录每次发送的成功数、失败数以及失败原因,方便后续排查问题;同时配置Firebase监控,及时发现发送异常。
内容的提问来源于stack exchange,提问作者Majoren
相关产品推荐
相关产品推荐

