使用Flutter Local Notification+FCM时后台/终止状态下通知不显示
问题排查与解决方案
1. 补全Flutter Local Notifications插件初始化流程
你的代码仅定义了安卓初始化配置,但未完成插件的初始化操作,这是后台/终止状态下无法显示通知的核心原因之一。修改main函数,补充初始化步骤:
Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await _configureLocalTimeZone(); await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); await FirebaseMessaging.instance.subscribeToTopic('debug'); // --- 新增插件初始化逻辑 --- const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('ic_stat_notification'); const InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid); await flutterLocalNotificationsPlugin.initialize(initializationSettings); // --- 初始化逻辑结束 --- final NotificationAppLaunchDetails? notificationAppLaunchDetails = !kIsWeb && Platform.isLinux ? null : await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails(); String initialRoute = HomePage.routeName; if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false) { selectedNotificationPayload = notificationAppLaunchDetails!.notificationResponse?.payload; initialRoute = SecondPage.routeName; } runApp( MaterialApp( initialRoute: initialRoute, routes: <String, WidgetBuilder>{ HomePage.routeName: (_) => HomePage(notificationAppLaunchDetails), SecondPage.routeName: (_) => SecondPage(selectedNotificationPayload) }, ), ); }
2. 调整FCM消息类型,触发后台处理器
应用处于后台/终止状态时:
- 仅包含
notification字段的纯通知消息会由系统直接展示,不会触发firebaseMessagingBackgroundHandler - 必须发送仅包含
data字段的数据消息,或同时包含notification和data字段并配置click_action: FLUTTER_NOTIFICATION_CLICK(安卓),才能触发后台处理器
示例数据消息结构(发送时使用):
{ "to": "/topics/debug", "data": { "title": "big text title", "body": "silent body", "bigText": "Lorem ipsum dolor sit amet, consectetur adipiscing elit..." } }
之后在后台处理器中从message.data提取字段,动态构建通知内容,避免写死固定文本。
3. 优化后台处理器的通知调用逻辑
确保flutterLocalNotificationsPlugin是全局实例,同时优化通知ID的生成逻辑,避免后台环境中ID重置问题:
@pragma('vm:entry-point') Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async { await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); print('A Background message just showed up : ${message.messageId}'); // 从data字段提取动态内容 final String title = message.data['title'] ?? 'Default Title'; final String body = message.data['body'] ?? 'Default Body'; final String bigText = message.data['bigText'] ?? 'Default Big Text'; const BigTextStyleInformation bigTextStyleInformation = BigTextStyleInformation( bigText, htmlFormatBigText: true, contentTitle: 'News Shot notification', htmlFormatContentTitle: true, summaryText: 'summary text', htmlFormatSummaryText: true, ); AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails( 'big text channel id', 'big text channel name', channelDescription: 'big text channel description', styleInformation: bigTextStyleInformation, importance: Importance.max, priority: Priority.high, // 确保后台状态下通知能正常弹出 ); NotificationDetails notificationDetails = NotificationDetails(android: androidNotificationDetails); // 使用消息ID作为通知ID,避免重复或重置问题 await flutterLocalNotificationsPlugin.show( int.tryParse(message.messageId ?? '0') ?? 0, title, body, notificationDetails); }
4. 检查安卓Manifest配置
- 添加Android 13+所需的通知权限:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
- 配置默认通知通道,避免因通道缺失导致通知不显示:
<application ...> <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="big text channel id" /> <!-- 与代码中使用的通道ID保持一致 --> </application>
验证步骤
- 先测试前台状态下发送数据消息,确认后台处理器被调用、本地通知正常显示
- 再测试后台/终止状态,发送相同的数据消息,检查终端日志是否打印
A Background message just showed up,并确认通知显示
内容的提问来源于stack exchange,提问作者austin
相关产品推荐
相关产品推荐

