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

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头,重复设置可能触发跨域头重复的报错

内容的提问来源于stack exchange,提问作者오민용

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 14:12:16