Firebase Messaging v1发送推送报401 PROJECT_NOT_PERMITTED错误
问题背景
运行搭载Firebase Admin SDK的Node服务时,每次尝试从服务端发送推送通知都会返回401错误,获取到的完整错误信息如下:
errorInfo: { code: 'messaging/authentication-error', message: 'An error occurred when trying to authenticate to the FCM servers. Make sure the credential used to authenticate this SDK has the proper permissions. Raw server response: "<HTML>\n' + '<HEAD>\n' + '<TITLE>PROJECT_NOT_PERMITTED</TITLE>\n' + '</HEAD>\n' + '<BODY BGCOLOR="#FFFFFF" TEXT="#000000">\n' + '<H1>PROJECT_NOT_PERMITTED</H1>\n' + '<H2>Error 401</H2>\n' + '</BODY>\n' + '</HTML>\n' + '". Status code: 401.' }, codePrefix: 'messaging'
已完成的排查操作
- 已完成服务账号配置,下载了对应.json密钥文件
- 已进入Google Cloud平台为服务账号添加了所有疑似必要的相关权限,服务账号权限配置如下:

- 本地服务初始化代码如下:
const admin = require('firebase-admin'); const messaging = require('firebase-admin/messaging'); const serviceAccount = require('<path-to-key>'); const fbApp = admin.initializeApp({ credential: admin.credential.cert(serviceAccount), projectId: '<PROJECT_ID>', databaseURL: '<DB_URL>' });
- 已查阅v1版本官方文档,未定位到缺失的权限项
- 已确认本地通过
firebase login登录了正确的Google账号,排除账号登录错误问题 - 发送推送的业务代码如下:
const sendPushNotifications2 = async (topic, reminder) => { const payload = genPayload2(reminder); //await messaging.getMessaging(fbApp).sendToTopic(topic, payload); await admin.messaging(fbApp).sendToTopic(topic, payload); };
- 已校验密钥.json文件中的
client_id、client_email、private_key_id字段值正确,但未找到private_key属性的校验入口,未完成该字段的正确性校验。
排查方案(按优先级从高到低验证)
- 确认Firebase对应项目已正常开通Cloud Messaging服务
进入Firebase控制台对应项目的消息推送页面,确认服务状态正常,不存在项目欠费、功能被限制的情况。返回PROJECT_NOT_PERMITTED错误的核心原因绝大多数是项目层面未开通FCM服务,和服务账号的细粒度权限无关。 - 校验初始化代码中的项目ID与密钥所属项目完全匹配
多项目并行时很容易出现密钥属于A项目、代码里手动填写的projectId属于B项目的问题,直接读取密钥文件内自带的project_id字段即可,不需要手动硬编码,修改初始化配置如下:const fbApp = admin.initializeApp({ credential: admin.credential.cert(serviceAccount), projectId: serviceAccount.project_id, databaseURL: '<DB_URL>' }); - 重新生成服务账号密钥,排除私钥损坏问题
不需要手动校验private_key字段的正确性,直接在Google Cloud控制台对应服务账号的密钥管理页,新建并下载一份全新的JSON格式密钥,替换本地旧文件即可。密钥复制、下载过程中出现的私钥截断、换行丢失都会直接导致鉴权失败。 - 修正服务账号权限配置
不需要零散添加疑似相关的权限,直接给对应服务账号绑定Firebase Admin SDK Administrator Service Agent系统角色,即可满足FCM推送的全部鉴权要求,零散配权很容易出现依赖权限漏配的问题。 - 排查本地网络代理影响
如果本地运行时开启了HTTPS代理,部分代理的流量解密功能会破坏请求的鉴权签名,导致Google侧校验失败返回401。可以临时关闭代理测试,或给Node进程配置NO_PROXY规则,让FCM相关请求不走代理。 - 后续可升级API调用方式
代码中使用的sendToTopic属于旧版API,v1版本SDK推荐使用send方法构造消息体发送,该问题不会触发401错误,可在鉴权问题修复后再调整。
内容的提问来源于stack exchange,提问作者Tlal
相关产品推荐
相关产品推荐

