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包在代码里自动生成,避免频繁手动更新
- 用gcloud命令行的话,先安装gcloud工具,然后运行
二、修正你的推送代码里的关键问题
你的代码里有个核心错误:用旧的server key作为Bearer令牌,v1接口不认这个,必须换成上面生成的OAuth令牌。另外还有几个细节要补:
替换Authorization头
把代码里的'Authorization': 'Bearer $serverKey'改成'Authorization': 'Bearer $oauthToken',其中oauthToken是你生成的短期令牌。补全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'。
- 确认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
相关产品推荐
相关产品推荐

