Flutter集成FCM遇问题:Token重启变更与通知接收失败
Flutter FCM 集成问题解答
问题1:重启应用获取新Token,旧Token是否仍可用于推送未活跃应用?
- FCM Token并非每次重启都会刷新,通常仅在应用卸载重装、设备系统版本更新、设备安全设置变更等场景下才会触发更新。如果你的设备每次重启都拿到新Token,大概率是测试环境的特殊情况或配置存在异常。
- 旧Token一旦失效(触发刷新后),就无法再用来推送消息——不管应用是否处于活跃状态。要实现对未活跃应用的推送,必须保证后端存储的是最新的有效Token。
- 解决方案:在Flutter中监听Token刷新事件,一旦Token更新,立即同步到你的后端服务器:
这样后端始终持有有效Token,就能正常给未活跃的应用推送通知。FirebaseMessaging.instance.onTokenRefresh.listen((newToken) { // 将newToken发送到后端存储 });
问题2:活跃状态下未收到通知,还需哪些配置?
Android端配置
- 在
AndroidManifest.xml中添加通知权限:<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> - 声明Firebase消息服务(若使用自定义服务):
<service android:name=".MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> - Android 13及以上版本需动态请求通知权限:
import 'package:permission_handler/permission_handler.dart'; Future<void> requestNotificationPermission() async { final status = await Permission.notification.request(); if (status.isGranted) { // 权限已获取 } }
iOS端配置
- 在Xcode中开启
Push Notifications能力(项目配置 -> Signing & Capabilities -> 添加Capability -> Push Notifications)。 - 在
Info.plist中添加推送权限相关配置:<key>UIBackgroundModes</key> <array> <string>remote-notification</string> </array> <key>NSUserNotificationUsageDescription</key> <string>需要推送权限来接收通知</string> - 动态请求通知权限:
import 'package:firebase_messaging/firebase_messaging.dart'; Future<void> requestNotificationPermission() async { NotificationSettings settings = await FirebaseMessaging.instance.requestPermission( alert: true, badge: true, sound: true, ); if (settings.authorizationStatus == AuthorizationStatus.authorized) { // 权限已获取 } }
Flutter端消息处理
FCM在应用前台活跃状态下不会自动弹出系统通知,需要手动处理onMessage回调并显示本地通知:
- 添加
flutter_local_notifications依赖到pubspec.yaml。 - 初始化本地通知插件,并监听前台消息:
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin(); Future<void> initLocalNotifications() async { const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher'); const DarwinInitializationSettings initializationSettingsIOS = DarwinInitializationSettings(); const InitializationSettings initializationSettings = InitializationSettings( android: initializationSettingsAndroid, iOS: initializationSettingsIOS, ); await _notificationsPlugin.initialize(initializationSettings); } // Firebase初始化后监听前台消息 FirebaseMessaging.instance.onMessage.listen((RemoteMessage message) { RemoteNotification? notification = message.notification; AndroidNotification? android = message.notification?.android; if (notification != null && android != null) { _notificationsPlugin.show( notification.hashCode, notification.title, notification.body, NotificationDetails( android: AndroidNotificationDetails( 'your_channel_id', 'your_channel_name', importance: Importance.max, priority: Priority.high, ), ), ); } });
最后,务必确保在runApp之前完成Firebase初始化:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); await initLocalNotifications(); await requestNotificationPermission(); runApp(const MyApp()); }
内容的提问来源于stack exchange,提问作者Ralfeus
相关产品推荐
相关产品推荐

