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

Flutter使用Firebase Messaging编程推送通知失败求助

FCM推送返回200但设备收不到通知?解决OAuth密钥创建及代码问题

一、先搞定FCM v1接口需要的OAuth 2.0密钥

你用的是FCM v1版本的接口(https://fcm.googleapis.com/v1/...),这个接口不能用旧的服务器密钥(server key),必须用OAuth 2.0令牌。创建步骤如下:

  • 打开Firebase控制台,进入你的项目,点左侧「设置」>「服务帐户」
  • 点击「生成新的私钥」,下载JSON格式的密钥文件
  • 生成短期OAuth令牌:
    • 用gcloud命令行的话,先安装gcloud工具,然后运行 gcloud auth application-default print-access-token,直接复制输出的令牌就行(有效期1小时)
    • 嫌手动麻烦的话,也可以用dart的googleapis_auth包在代码里自动生成,避免频繁手动更新

二、修正你的推送代码里的关键问题

你的代码里有个核心错误:用旧的server key作为Bearer令牌,v1接口不认这个,必须换成上面生成的OAuth令牌。另外还有几个细节要补:

  1. 替换Authorization头
    把代码里的'Authorization': 'Bearer $serverKey'改成'Authorization': 'Bearer $oauthToken',其中oauthToken是你生成的短期令牌。

  2. 补全Android通知通道
    Android 8.0+必须配置通知通道,否则通知根本不会显示。先在代码里创建通道:

Future<void> createNotificationChannel() async {
  const AndroidNotificationChannel channel = AndroidNotificationChannel(
    'android_notify_channel', // 自定义通道ID
    '重要通知', // 通道名称
    description: '用于接收应用推送通知', // 通道描述
    importance: Importance.high,
  );

  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

  await flutterLocalNotificationsPlugin
      .resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
      ?.createNotificationChannel(channel);
}

然后在initState()里调用这个方法,同时把推送代码里的android.notification部分加上'channel_id': 'android_notify_channel'。

  1. 确认Topic订阅有效
    检查设备是否真的订阅了android_users:可以在Firebase控制台的「云消息传递」>「主题」里查看该主题的订阅数,确保你的测试设备在列表里。

三、修正后的完整推送代码示例

import 'package:http/http.dart' as http;
import 'dart:convert';

Future<void> sendNotificationToAll(String title, String body, String oauthToken) async {
  const String fcmEndpoint =
      'https://fcm.googleapis.com/v1/projects/你的项目ID/messages:send';

  final Map<String, dynamic> notification = {
    'message': {
      'topic': 'android_users',
      'notification': {
        'title': title,
        'body': body,
      },
      'android': {
        'priority': 'HIGH',
        'notification': {
          'channel_id': 'android_notify_channel', // 配置好的通道ID
        }
      },
      'data': {
        'click_action': 'FLUTTER_NOTIFICATION_CLICK',
        'id': '1',
        'status': 'done'
      },
    }
  };

  final response = await http.post(
    Uri.parse(fcmEndpoint),
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer $oauthToken', // 用OAuth令牌替换server key
    },
    body: json.encode(notification),
  );

  if (response.statusCode == 200) {
    print('通知发送成功:${response.body}');
  } else {
    print('发送失败:${response.body}');
  }
}

四、额外排查点

  • 检查测试设备有没有开通知权限,有没有联网
  • 去Firebase控制台的「云消息传递」>「报告」里看消息的送达统计,确认消息是不是真的发出去了
  • 确保你的App包名和Firebase项目里配置的包名完全一致

内容的提问来源于stack exchange,提问作者Andreas Hadjimamas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:05:14