Firebase后台状态通知无法弹窗问题求助(附代码)
解决方案:后台Firebase通知无法弹窗的问题
核心原因
当App处于后台时,Firebase发送的**通知消息(Notification Message)**会由Android系统直接处理,不会触发你的_firebaseBackgroundHandler,导致自定义的高优先级通知渠道和弹窗配置未生效,系统默认使用低优先级渠道仅将通知显示在状态栏。
具体修复步骤
1. 提前创建高优先级通知渠道
将通知渠道的创建逻辑移到App启动阶段执行,确保系统在后台收到通知前已存在高优先级渠道:
Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); // 初始化本地通知并创建高优先级渠道 await initLocalNotificationSetup(); FirebaseMessaging.onBackgroundMessage(_firebaseBackgroundHandler); runApp(const MyApp()); } // 抽离初始化逻辑,无需传入context Future<void> initLocalNotificationSetup() async { const AndroidNotificationChannel channel = AndroidNotificationChannel( 'high_importance_channel', 'High Importance Notifications', description: 'This channel is used for important notifications.', playSound: true, showBadge: true, enableLights: true, enableVibration: true, importance: Importance.max, ); final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); // 提前创建通知渠道 await flutterLocalNotificationsPlugin .resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>() ?.createNotificationChannel(channel); // 初始化本地通知设置 var androidInitialaztionSetting = const AndroidInitializationSettings('@mipmap/ic_launcher'); var iosInitialaztionSetting = const DarwinInitializationSettings(); var initializationSettings = InitializationSettings( android: androidInitialaztionSetting, iOS: iosInitialaztionSetting, ); await flutterLocalNotificationsPlugin.initialize( initializationSettings, onDidReceiveNotificationResponse: (payload) { // 这里处理通知点击逻辑,如需context可通过全局key获取 }, ); // 设置前台通知展示选项 await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( alert: true, badge: true, sound: true, ); }
2. 调整后台消息处理逻辑
若需要后台收到消息时也自定义弹窗,需发送数据消息(Data Message)(Firebase控制台选择「自定义数据」模式),然后在后台handler中手动触发本地通知:
@pragma('vm:entry-point') Future<void> _firebaseBackgroundHandler(RemoteMessage message) async { await Firebase.initializeApp(); final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); // 复用高优先级渠道配置 const AndroidNotificationChannel channel = AndroidNotificationChannel( 'high_importance_channel', 'High Importance Notifications', description: 'This channel is used for important notifications.', playSound: true, showBadge: true, enableLights: true, enableVibration: true, importance: Importance.max, ); AndroidNotificationDetails androidNotificationDetails = const AndroidNotificationDetails( channel.id, channel.name, playSound: true, enableLights: true, enableVibration: true, channelDescription: 'your channel description', importance: Importance.high, priority: Priority.high, ticker: 'ticker', largeIcon: DrawableResourceAndroidBitmap("ic_launcher"), styleInformation: MediaStyleInformation( htmlFormatContent: true, htmlFormatTitle: true, ), ); DarwinNotificationDetails darwinNotificationDetails = const DarwinNotificationDetails( presentAlert: true, presentBadge: true, presentSound: true); NotificationDetails notificationDetails = NotificationDetails( android: androidNotificationDetails, iOS: darwinNotificationDetails, ); // 显示自定义通知,用时间戳做ID避免通知被覆盖 await flutterLocalNotificationsPlugin.show( DateTime.now().millisecondsSinceEpoch, message.data['title'], message.data['body'], notificationDetails, ); }
3. 检查AndroidManifest配置
确保已添加必要的权限和Firebase服务配置:
<!-- 通知相关权限 --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.VIBRATE" /> <!-- Firebase Messaging服务声明 --> <service android:name="com.google.firebase.messaging.FirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
关键注意点
- 通知消息(Notification Message)后台由系统处理,仅会使用提前创建的渠道配置;
- 数据消息(Data Message)会触发
_firebaseBackgroundHandler,可完全自定义通知展示; - 渠道的
importance必须设为Importance.max或Importance.high才能触发弹窗。
内容的提问来源于stack exchange,提问作者Shafi Munshi
相关产品推荐
相关产品推荐

