Firebase Cloud Messaging sendEach报错:RS256需用非对称密钥
问题分析与解决方案
问题核心
Firebase Messaging send() 方法正常,但 sendEach() 在处理第二组及以后的消息数组时抛出 secretOrPrivateKey must be an asymmetric key when using RS256 错误,第一组约490条消息可正常发送,后续组失败,运行环境为BullMQ Worker。
可能原因
- Firebase实例状态异常:循环中重复调用
messagingService.of("namedNotification")可能导致实例上下文被污染,或JWT令牌缓存失效后重新生成时使用了错误的密钥类型。 - BullMQ Worker进程隔离:Worker的多进程/线程环境中,Firebase SDK的全局状态(如令牌缓存)未正确共享,导致后续请求中SDK尝试使用非RS256要求的密钥。
- 密钥配置未正确绑定到命名实例:
namedNotification命名实例的初始化可能未正确传入服务账号私钥,仅在首次调用时复用了默认实例的配置,后续调用时配置丢失。
解决方案
1. 复用Messaging实例,避免重复创建
将命名实例提前初始化并复用,不要在循环中反复调用 of():
// 提前获取实例,避免循环内重复创建 const messagingInstance = messagingService.of("namedNotification"); for (let index = 0; index < smallDatas.length; index++) { if (index % 100 === 0) { logService.logNotification( `namedNotification - send: {title: ${title}, body: ${body}, language: ${language}, operation: ${operation}}. Process: ${ index + 1 }/${smallDatas.length}` ); } await messagingInstance .sendEach(smallDatas[index]) .catch((error) => console.log("Notification Error : " + error)); }
2. 验证命名实例的初始化配置
确保 namedNotification 实例初始化时,正确传入了Firebase服务账号的JSON私钥(RS256要求的非对称密钥):
// 示例:正确初始化命名实例 import { initializeApp, cert, getApps } from "firebase-admin/app"; import { getMessaging } from "firebase-admin/messaging"; const config = { credential: cert("./service-account-key.json"), // 确保是从Firebase控制台下载的私钥JSON projectId: "your-project-id" }; // 避免重复初始化 if (!getApps().some(app => app.name === "namedNotification")) { initializeApp(config, "namedNotification"); } const messagingService = getMessaging(getApps().find(app => app.name === "namedNotification"));
3. 禁用Firebase SDK的令牌缓存(临时排查)
如果是缓存导致的密钥错误,可以尝试禁用令牌缓存,强制每次请求重新生成合法令牌:
// 在初始化实例时配置缓存选项 const messagingInstance = getMessaging(app); messagingInstance.setTokenCache({ get: () => Promise.resolve(null), set: () => Promise.resolve() });
4. 检查BullMQ Worker的执行上下文
确保Worker进程中Firebase实例的初始化是单例的,避免每个任务都重新初始化实例。可以在Worker启动时提前初始化Firebase,而不是在任务处理函数内初始化。
排查步骤
- 打印
messagingInstance的配置信息,确认每次调用时密钥类型是否为RS256对应的私钥。 - 尝试将第二组消息替换为第一组的内容,看是否依然报错,排除消息内容本身的问题。
- 在本地环境模拟BullMQ Worker的执行,复现问题并调试密钥加载流程。
内容的提问来源于stack exchange,提问作者Gökay Demirel
相关产品推荐
相关产品推荐

