You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter集成FCM时onBackgroundMessage触发崩溃,通知无法显示求助

问题解决方案

一、修复应用终止状态下FCM崩溃问题

你的onBackgroundMessage使用匿名函数的方式不符合FCM后台消息处理要求,必须使用顶级异步函数,且函数内部需要重新初始化Firebase(后台隔离环境无默认初始化)。修改如下:

// 必须是顶级函数,不能放在类或方法内部
Future<void> firebaseMessagingBackgroundHandler(Map<String, dynamic> message) async {
  await Firebase.initializeApp();
  print("Handling a background message: ${message['data']}");
  // 后台消息触发本地通知
  await showNotification(message);
}

// 初始化FCM监听逻辑
void setupFCM() {
  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    print("Foreground message data: ${message.data}");
    showNotification(message);
  });

  FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
    print("Resumed message data: ${message.data}");
    // 应用从后台恢复后的自定义逻辑
  });

  // 绑定后台消息处理函数,必须指向顶级函数
  FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
}

关键注意点:

  • onBackgroundMessage只能绑定顶级函数,匿名函数会导致应用终止时崩溃
  • 后台函数内必须手动初始化Firebase,否则无法正常调用Firebase相关API

二、集成flutter_local_notifications解析FCM数据并显示通知

1. 初始化本地通知插件

在应用启动时(如initState)完成初始化:

FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

Future<void> initLocalNotifications() async {
  // Android初始化配置
  const AndroidInitializationSettings androidInitSettings =
      AndroidInitializationSettings('@mipmap/ic_launcher');
  
  // iOS初始化配置
  const IOSInitializationSettings iosInitSettings =
      IOSInitializationSettings();
  
  const InitializationSettings initSettings =
      InitializationSettings(
          android: androidInitSettings,
          iOS: iosInitSettings);
  
  await flutterLocalNotificationsPlugin.initialize(initSettings,
    // 可选:处理通知点击事件
    onSelectNotification: (String? payload) async {
      if (payload != null) {
        Map<String, dynamic> data = jsonDecode(payload);
        print('通知点击数据:$data');
        // 这里可添加页面跳转等逻辑
      }
    });
}

2. 解析FCM消息并显示通知

完善showNotification函数,兼容FCM的两种消息格式(RemoteMessage和旧版Map):

import 'dart:convert';

Future<void> showNotification(dynamic message) async {
  String title;
  String body;
  Map<String, dynamic> data;

  // 适配新版FCM RemoteMessage格式
  if (message is RemoteMessage) {
    title = message.notification?.title ?? '系统通知';
    body = message.notification?.body ?? '收到一条新消息';
    data = message.data;
  } 
  // 兼容旧版Map格式
  else if (message is Map<String, dynamic>) {
    title = message['notification']?['title'] ?? message['data']?['title'] ?? '系统通知';
    body = message['notification']?['body'] ?? message['data']?['body'] ?? '收到一条新消息';
    data = message['data'] ?? {};
  } 
  // 默认兜底
  else {
    title = '未知通知';
    body = '收到一条未知消息';
    data = {};
  }

  var androidDetails = AndroidNotificationDetails(
    'fcm_notification_channel', // 渠道ID必须唯一
    'FCM通知渠道',
    '用于显示FCM推送的通知',
    importance: Importance.max,
    priority: Priority.high,
    showWhen: true,
  );
  var iosDetails = IOSNotificationDetails();
  var platformDetails = NotificationDetails(android: androidDetails, iOS: iosDetails);

  // 显示通知,用时间戳作为id避免重复覆盖
  await flutterLocalNotificationsPlugin.show(
    DateTime.now().millisecond,
    title,
    body,
    platformDetails,
    payload: jsonEncode(data), // 将消息数据转为JSON字符串,点击时可获取
  );
}

三、额外注意事项

  • 确保AndroidManifest.xml和Info.plist已配置好FCM所需的权限、服务和推送证书
  • 应用终止状态下,FCM的notification类型消息由系统直接显示,data类型消息需要通过onBackgroundMessage触发本地通知
  • 测试后台推送建议使用真实设备,部分模拟器对后台消息支持不完善

内容的提问来源于stack exchange,提问作者mideveloper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:45:42