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

Flutter通知推送数据处理失效,请求排查与修改方案

Flutter Firebase推送通知数据解析问题排查与修复

问题概述

开发Flutter应用时,处理Firebase推送通知的data嵌套字段时,数据解析未生效,无法正确获取嵌套数据。已配置onMessage监听和后台消息处理函数,但processdata解析逻辑存在错误。

后端推送代码(PHP)

$fields = array (  
    'to' => $id,
    'notification' => array (   
        "title" =>  $title,
        "body" =>  $message,
    ),      
    'data' => array (
        "title" =>  $title,
        "message" =>  $message,
        "type" => $type,
        "responseId" => $responseId,
        "prompterType" => $prompterType
    )
);

推送数据示例

Array ( [type] => Grouping [responseId] => 250 [message] => Array ( [daodao0912@gmail.com] => Array ( [name] => mai mai [matches] => tai, dao [table] => 1 ) ) [prompterType] => -1 )
string(143) "{"multicast_id":3893029672353112501,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1662052156406640%014b8671014b8671"}]}" 

Flutter端原代码(main.dart)

final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
    FlutterLocalNotificationsPlugin();
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  print('Handling a background message ${message.messageId}');
  Map<String,dynamic> data = message.data;
  processdata(data);
  getDataRound1();
  getDataRound2();
}

Future<void> main() async{
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: const FirebaseOptions(
    apiKey: 'AIzaSyCGPCpK9XxKgxTzfnXOSA-9HAeIWtQ0Zhk',
    appId: '1:22990997901:android:60a134f76b798158c995c4',
    messagingSenderId: '22990997901',
    projectId: 'activepeers-ai',
    storageBucket: 'activepeers-ai.appspot.com',
  )
  );
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);


  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    print('Got a message whilst in the foreground!');
    print('Message data: ${message.data}');

    if (message.notification != null) {
      print('Message also contained a notification: ${message.notification}');
    }
  });

  const AndroidNotificationChannel channel = AndroidNotificationChannel(
    'high_importance_channel', // id
    'High Importance Notifications', // title
    importance: Importance.max,
  );

  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
  FlutterLocalNotificationsPlugin();

  await flutterLocalNotificationsPlugin
      .resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
      ?.createNotificationChannel(channel);

  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    RemoteNotification? notification = message.notification;
    AndroidNotification? android = message.notification?.android;
    print('${message.messageId}');
    if (notification != null && android != null) {
      flutterLocalNotificationsPlugin.show(
          notification.hashCode,
          notification.title,
          notification.body,
          NotificationDetails(
            android: AndroidNotificationDetails(
              channel.id,
              channel.name,
              icon: android.smallIcon,
            ),
          ));
    }
  });
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      home: SplashScreen(),
    );
  }
}

原数据处理函数

String type = '';
String responseId = '';
int prompterType = 0;
String name ='';
String matching = '';
int table = 0;
void processdata(Map<String,dynamic> data) async{
  type = data["type"];
  responseId = data["responseId"];
  prompterType = data["prompterType"];
  Map<String,dynamic>personalInfo = data["message"][0];
  name = personalInfo["name"];
  matching = personalInfo["matches"];
  table = personalInfo["table"];
}

问题排查与修复方案

1. 重复注册onMessage监听

原代码注册了两次FirebaseMessaging.onMessage.listen,仅最后一次监听生效,且第一次监听未调用processdata处理数据。合并两次监听,在同一个回调内完成日志打印、通知展示和数据处理。

2. data["message"]解析逻辑错误

从推送数据示例可见,message是一个以邮箱为键的Map({daodao0912@gmail.com: {...}}),而非数组,原代码data["message"][0]的写法完全错误,需通过values.first获取Map中的嵌套数据。

3. 类型转换缺失

Firebase推送的data字段所有值默认是字符串类型,直接赋值给int变量会报错,需用int.parse()转换,同时处理可能的null值。

4. 后台函数重复初始化Firebase

_firebaseMessagingBackgroundHandler中重复调用Firebase.initializeApp,main函数已完成初始化,可移除该代码(若后台需使用其他Firebase服务则保留)。

5. 空安全处理缺失

原全局变量未处理null情况,需添加空安全判断避免运行时异常。

修改后的代码

修改后的processdata函数

String type = '';
String responseId = '';
int prompterType = 0;
String name ='';
String matching = '';
int table = 0;

void processdata(Map<String,dynamic> data) {
  // 处理顶层字段,添加空安全判断
  type = data["type"] ?? '';
  responseId = data["responseId"] ?? '';
  prompterType = int.tryParse(data["prompterType"] ?? '0') ?? 0;

  // 解析嵌套的message字段
  if (data["message"] is Map) {
    Map<String,dynamic> messageMap = data["message"] as Map<String,dynamic>;
    // 获取第一个嵌套数据(推送示例中仅一个邮箱键)
    if (messageMap.values.isNotEmpty) {
      Map<String,dynamic> personalInfo = messageMap.values.first as Map<String,dynamic>;
      name = personalInfo["name"] ?? '';
      matching = personalInfo["matches"] ?? '';
      table = int.tryParse(personalInfo["table"] ?? '0') ?? 0;
    }
  }

  // 打印解析结果验证
  print('解析结果:type=$type, responseId=$responseId, name=$name, table=$table');
}

修改后的main函数onMessage监听

// 合并重复的onMessage监听
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
  print('Got a message whilst in the foreground!');
  print('Message data: ${message.data}');

  // 处理推送数据
  processdata(message.data);

  RemoteNotification? notification = message.notification;
  AndroidNotification? android = message.notification?.android;
  print('${message.messageId}');

  if (notification != null && android != null) {
    flutterLocalNotificationsPlugin.show(
        notification.hashCode,
        notification.title,
        notification.body,
        NotificationDetails(
          android: AndroidNotificationDetails(
            channel.id,
            channel.name,
            icon: android.smallIcon,
          ),
        ));
  }
});

修改后的后台处理函数

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  // main已初始化Firebase,此处移除重复初始化
  print('Handling a background message ${message.messageId}');
  Map<String,dynamic> data = message.data;
  processdata(data);
  getDataRound1();
  getDataRound2();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 19:35:23