Flutter Web下Firebase云函数发送FCM报Admin SDK认证错误
Flutter Web 调用Firebase云函数发送FCM报401认证错误排查
问题现象
在Flutter Web环境中通过Firebase Cloud Function实现FCM消息推送能力时,功能始终无法正常运行,云函数日志返回认证类错误。
现有实现代码
/* eslint-disable max-len */ const admin = require("firebase-admin"); const {applicationDefault} = require("firebase-admin/app"); const functions = require("firebase-functions"); const cors = require("cors")({origin: true}); admin.initializeApp({credential: applicationDefault(), databaseURL: "https://<PROJECT-ID>.firebaseio.com"}); const messaging = admin.messaging(); exports.sendNoti = functions.runWith({ allowInvalidAppCheckToken: true}).https.onRequest(async (req, res) => { cors(req, res, async () =>{ if (res.app == undefined) { console.log("App Check failed-precondition / The function must be called from an App Check verified app."); } console.log(res.app); try { await messaging.sendToDevice(req.body.data.targetDevices, { notification: { title: req.body.data.messageTitle, body: req.body.data.messageBody, }, }); res.set("Access-Control-Allow-Origin", "*"); res.status(200).send({"status": "success", "data": "GOOD"}); return true; } catch (ex) { console.log(ex); res.set("Access-Control-Allow-Origin", "*"); res.status(200).send({"status": "fail", "data": ex}); return ex; } }); });
报错详情
{errorInfo: {code: messaging/authentication-error, message: 尝试向FCM服务器认证时发生异常,需确认用于SDK认证的凭证拥有正确权限。原始服务端返回HTML格式响应,状态码:401。}, codePrefix: messaging}
核心错误:FCM服务端返回401未授权状态,判定为SDK认证凭证权限不匹配。
已尝试排查方案
- 初始化Admin SDK时配置
credential: admin.credential.applicationDefault()使用默认应用凭证 - 导入service.json服务账号文件,通过
admin.credential.cert("service.json")显式指定认证凭证 - 将HTTP触发型云函数替换为OnCall类型实现推送逻辑
- 接入App Check校验能力
以上方案全部尝试后仍未解决认证错误问题。
可落地排查解决步骤
按优先级从高到低排查,90%以上的同类问题都是前两个原因导致的:
- 废弃API调用问题
你代码里用的messaging.sendToDevice()是基于旧版FCM Legacy HTTP API实现的,2024年6月之后新建的Firebase项目默认不再开放Legacy API的授权访问,旧项目也在逐步关停该接口的权限,调用必然返回401。
直接替换为官方推荐的V1版本接口即可,对应修改后的发送逻辑代码:
// 单设备推送写法 const message = { notification: { title: req.body.data.messageTitle, body: req.body.data.messageBody, }, token: req.body.data.targetDevice } await messaging.send(message) // 多设备批量推送写法,替换上面的单设备逻辑即可 await messaging.sendEachForMulticast({ tokens: req.body.data.targetDevices, notification: { title: req.body.data.messageTitle, body: req.body.data.messageBody, } })
- FCM API服务未启用
进入对应项目的Google Cloud控制台,搜索找到「Firebase Cloud Messaging API」服务,确认服务状态为已启用,新创建的项目默认不会自动开启该服务,凭证正确但服务未开启时同样会返回401。启用后等待1-2分钟配置生效再重试即可。 - 初始化配置错误
检查admin.initializeApp中的databaseURL配置,将<PROJECT-ID>替换为你当前部署云函数的真实项目ID,字符不匹配会直接导致凭证校验失败。
如果是本地调试云函数时触发错误,不要直接使用applicationDefault(),本地环境默认读取的是本机登录的gcloud账号凭证,需要先执行firebase use 你的项目ID关联目标项目,再显式指定服务账号密钥的绝对路径加载凭证,避免读不到文件导致认证失败。 - 代码逻辑问题修正
- App Check校验结果挂载在
req.app对象下,你代码里写的res.app永远是undefined,会导致校验逻辑完全失效 - CORS配置已经通过cors中间件设置了
origin: true,不需要在try/catch块中重复设置Access-Control-Allow-Origin头,重复设置可能触发跨域头重复的报错
- App Check校验结果挂载在
内容的提问来源于stack exchange,提问作者오민용
相关产品推荐
相关产品推荐

