Flutter中用SharedPreference保存Firebase推送通知仅存最新项,如何解决?
解决Firebase推送通知仅保存最新一条的问题
问题根源
- 你当前用
sharedPreferences.setString('notification', jsonData)每次都会覆盖同一个key下的旧数据,导致只能保留最新一条通知。 - 读取逻辑只处理了单条数据,没有读取并解析整个通知列表。
修复步骤及代码修改
1. 修改保存通知的方法
先读取已有的通知列表,添加新通知后再保存整个列表,避免覆盖:
void saveNotification(String title, String body) async { // 读取已保存的通知字符串列表,为空则初始化空列表 List<String> existingNotifications = sharedPreferences.getStringList('notifications') ?? []; // 创建新通知并转为JSON字符串 NotificationModel newNotification = NotificationModel(title: title, body: body); String newNotificationJson = jsonEncode(newNotification.toMap()); // 将新通知加入列表 existingNotifications.add(newNotificationJson); // 保存更新后的完整列表 await sharedPreferences.setStringList('notifications', existingNotifications); print('通知已保存,当前总数: ${existingNotifications.length}'); }
2. 修改读取数据的方法
读取整个字符串列表,逐个解析为NotificationModel并加入展示列表:
void initializeData() async { sharedPreferences = await SharedPreferences.getInstance(); // 获取保存的通知字符串列表 List<String>? savedNotifications = sharedPreferences.getStringList('notifications'); if (savedNotifications != null && savedNotifications.isNotEmpty) { // 清空现有列表避免重复加载 notificationList.clear(); // 逐个解析并添加到展示列表 for (String notificationJson in savedNotifications) { Map<String, dynamic> notificationMap = jsonDecode(notificationJson); NotificationModel model = NotificationModel.fromMap(notificationMap); notificationList.add(model); } print('已加载${notificationList.length}条通知'); } }
3. 修正NotificationModel的适配问题
你的模型中没有定义fromJson方法,之前代码里的NotificationModel.fromJson(result)会报错,直接用已有的fromMap即可(jsonDecode返回的是Map类型),模型代码保持原样即可:
class NotificationModel extends Equatable { final String title; final String body; const NotificationModel({ required this.title, required this.body, }); NotificationModel copyWith({ String? title, String? body, }) { return NotificationModel( title: title ?? this.title, body: body ?? this.body, ); } Map<String, dynamic> toMap() { return <String, dynamic>{ 'title': title, 'body': body, }; } factory NotificationModel.fromMap(Map<String, dynamic> map) { return NotificationModel( title: map['title'] as String, body: map['body'] as String, ); } }
4. Firebase消息监听逻辑微调
确保调用saveNotification时参数非空,避免空指针:
FirebaseMessaging.onMessage.listen( (event) { RemoteNotification? notification = event.notification; AndroidNotification? android = event.notification?.android; if (notification != null && android != null) { _localNotificationsPlugin.show( notification.hashCode, notification.title, notification.body, NotificationDetails( android: AndroidNotificationDetails(channel.id, channel.name, channelDescription: channel.description, icon: '@mipmap/ic_launcher'), ), ); } // 确认title和body非空再保存 if (notification?.title != null && notification?.body != null) { saveNotification(notification.title!, notification.body!); print('数据保存成功'); } }, );
额外提示
- 可以给
NotificationModel添加timestamp字段,方便后续按时间排序展示通知 - 如果通知数量较多,SharedPreferences性能有限,可考虑改用本地数据库(如Hive、sqflite)存储
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

