Flutter应用中Firebase Cloud Messaging后台通知接收失败求助
Flutter应用中Firebase Cloud Messaging后台通知接收失败求助
我看了你贴的代码,后台收不到FCM通知主要是几个常见的配置坑,我帮你一步步梳理修复:
1. 最关键的问题:后台消息回调不能用类实例方法
你把handleBackgroundMessage写在FirebaseAPI类里当实例方法了,但FCM的onBackgroundMessage要求回调必须是顶层函数(写在类外面)或者静态方法!因为应用切到后台时,Flutter会在独立的隔离进程里执行这个回调,根本访问不到类的实例成员,所以当前写法会导致后台消息直接静默失败,连你写的print都不会执行。
修复:把回调改成顶层函数
// 把这个函数移到FirebaseAPI类外面,变成全局顶层函数 Future<void> handleBackgroundMessage(RemoteMessage message) async { print("后台收到消息:Title: ${message.notification?.title}, Body: ${message.notification?.body}"); // 后面还要加显示通知的代码,别急 } class FirebaseAPI { final _firebaseMessaging = FirebaseMessaging.instance; Future<void> initNotification() async { await _firebaseMessaging.requestPermission(); final fcmToken = await _firebaseMessaging.getToken(); print("fcmtoken: ${fcmToken}"); // 现在传这个顶层函数给onBackgroundMessage FirebaseMessaging.onBackgroundMessage(handleBackgroundMessage); } }
2. 后台消息不会自动弹通知,得靠本地通知库
FCM只是帮你把消息传过来,不会自动在系统状态栏弹出通知(尤其是Android 8.0+必须要有通知渠道才能显示),你得用flutter_local_notifications这类本地通知库手动构建并弹出通知。
一步一步配:
(1)先加依赖
在pubspec.yaml里添加:
dependencies: flutter_local_notifications: ^16.1.0 # 用最新的稳定版就行
(2)修改FirebaseAPI,集成本地通知
既要初始化本地通知渠道,还要在后台回调里手动弹通知:
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; // 还是这个顶层函数,现在加显示通知的逻辑 Future<void> handleBackgroundMessage(RemoteMessage message) async { // 后台隔离环境要重新初始化本地通知 final localNotifications = FlutterLocalNotificationsPlugin(); const androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); // 用你自己的应用图标 const initSettings = InitializationSettings(android: androidInit); await localNotifications.initialize(initSettings); // 拿到FCM的通知内容,弹出来 final notification = message.notification; if (notification != null) { await localNotifications.show( notification.hashCode, notification.title, notification.body, const NotificationDetails( android: AndroidNotificationDetails( 'app_notifications', // 自定义渠道ID,和后面配置一致 '应用通知', // 渠道名称,用户能在系统设置里看到 importance: Importance.max, priority: Priority.high, ), ), ); } } class FirebaseAPI { final _firebaseMessaging = FirebaseMessaging.instance; final _localNotifications = FlutterLocalNotificationsPlugin(); Future<void> initNotification() async { // 1. 请求FCM通知权限 await _firebaseMessaging.requestPermission( alert: true, badge: true, sound: true, ); // 2. 初始化本地通知(前台显示通知用) const androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); const initSettings = InitializationSettings(android: androidInit); await _localNotifications.initialize(initSettings); // 3. 前台收到消息时也弹通知(可选,看你需求) FirebaseMessaging.onMessage.listen((message) { final notification = message.notification; if (notification != null) { _localNotifications.show( notification.hashCode, notification.title, notification.body, const NotificationDetails( android: AndroidNotificationDetails( 'app_notifications', '应用通知', importance: Importance.max, priority: Priority.high, ), ), ); } }); // 4. 获取并打印FCM Token final fcmToken = await _firebaseMessaging.getToken(); print("fcmtoken: ${fcmToken}"); // 5. 绑定后台消息回调 FirebaseMessaging.onBackgroundMessage(handleBackgroundMessage); } }
3. Android端的额外配置检查
(1)完善build.gradle
你的build.gradle已经加了Firebase BOM,但最好显式添加messaging依赖,确保版本正确:
dependencies { implementation(platform("com.google.firebase:firebase-bom:32.7.2")) implementation("com.google.firebase:firebase-crashlytics") implementation("com.google.firebase:firebase-analytics") implementation("com.google.firebase:firebase-messaging") // 加这一行 implementation "androidx.multidex:multidex:2.0.1" }
(2)配置通知渠道到AndroidManifest
在android/app/src/main/AndroidManifest.xml的<application>标签里加:
<!-- 指定默认通知渠道ID,和代码里的一致 --> <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="app_notifications" />
最后再排查这几点
- 确认你在Firebase控制台发测试消息时,用的是代码里打印的那个
fcmtoken,别输错; - 测试后台通知一定要把应用切到后台(完全退出或者退到桌面,别在前台调试);
- 检查设备上你的应用通知权限有没有开,有没有被设成静默通知;
- 如果是iOS测试,必须用真机(模拟器不支持FCM后台通知),还要配置好APNs证书。
先把“后台回调改成顶层函数”这个核心问题修了,再逐步配本地通知,应该就能解决后台收不到通知的问题了!
备注:内容来源于stack exchange,提问作者Emad Younan
相关产品推荐
相关产品推荐

