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
相关产品推荐
相关产品推荐

