无法将Firestore返回的DocumentData列表存入GetX Storage报错求助
问题原因
- GetX Storage仅支持存储JSON可序列化的基础类型(String、int、bool、List、Map等),你直接传入
RxList<DocumentData>类型的自定义对象列表,框架无法直接对自定义类实例做序列化,所以抛出转换失败错误。 - 你的
DocumentData类里的timer字段是Firebase的Timestamp类型,该类型本身也不属于JSON原生支持的类型,直接序列化也会触发报错。
解决方案
步骤1:调整DocumentData的序列化逻辑,兼容Timestamp类型转换
修改模型类的toJson和fromJson方法,将Timestamp类型转换为可序列化的毫秒数存储,读取时再反向转换回来:
class DocumentData { DocumentData({ required this.uid, required this.timer, required this.itemName, required this.isSelectedItem, }); String uid; Timestamp timer; String itemName; bool isSelectedItem; factory DocumentData.fromJson(Map<String, dynamic> json) => DocumentData( uid: json["uid"], // 读取时将存储的毫秒数转回Timestamp类型 timer: Timestamp.fromMillisecondsSinceEpoch(json["timer"]), itemName: json["itemName"], isSelectedItem: json["isSelectedItem"], ); Map<String, dynamic> toJson() => { "uid": uid, // 存储时将Timestamp转换为int类型的毫秒数 "timer": timer.millisecondsSinceEpoch, "itemName": itemName, "isSelectedItem": isSelectedItem, }; }
步骤2:写入存储前将自定义对象列表转换为可序列化的Map列表
调整获取数据后的存储逻辑,先把所有DocumentData实例转为Map再存入GetX Storage:
//Function to get the all todos from firestore getAllTodosFromFirestore() async { await todos.where('uid', isEqualTo: uid).get().then((value) { final todoList = value.docs.map((e) => DocumentData.fromJson(e.data() as Map<String,dynamic>)).toList(); Get.find<TodoController>().todoList.value = todoList; // 转换为可序列化的Map列表后再写入 final serializableTodoList = todoList.map((item) => item.toJson()).toList(); GetStoragePref.instance.writeValues('todos_list', serializableTodoList); }); return Get.find<TodoController>().todoList; }
步骤3:读取存储数据时反向转换为DocumentData列表
读取存储内容时,把拿到的Map列表转回DocumentData对象即可使用:
List<DocumentData> getLocalTodos() { final List? storedList = GetStoragePref.instance.readValues('todos_list'); if (storedList == null) return []; return storedList.map((item) => DocumentData.fromJson(item as Map<String, dynamic>)).toList(); }
内容的提问来源于stack exchange,提问作者Rajan
相关产品推荐
相关产品推荐

