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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 09:31:05