Flutter项目Firebase+GetStorage状态更新报错:_JsonDocumentReference异常
Flutter Firebase与GetStorage状态更新问题修复
问题1:数据库更新成功,但抛出序列化异常
控制台报错:
E/flutter ( 2958): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Converting object to an encodable object failed: Instance of '_JsonDocumentReference' E/flutter ( 2958): #0 _JsonStringifier.writeObject (dart:convert/json.dart:794:7) E/flutter ( 2958): #1 _JsonStringifier.writeMap (dart:json.dart:875:7) E/flutter ( 2958): #2 _JsonStringifier.writeJsonValue (dart:json.dart:830:21) E/flutter ( 2958): #3 _JsonStringifier.writeObject (dart:json.dart:785:9) E/flutter ( 2958): #4 _JsonStringStringifier.printOn (dart:json.dart:983:17) E/flutter ( 2958): #5 _JsonStringStringifier.stringify (dart:json.dart:968:5) E/flutter ( 2958): #6 JsonEncoder.convert (dart:json.dart:345:30) E/flutter ( 2958): #7 JsonCodec.encode (dart:json.dart:231:45) E/flutter ( 2958): #8 StorageImpl.flush (package:get_storage/src/storage/io.dart:34:37) E/flutter ( 2958): #9 GetStorage._flush (package:get_storage/src/storage_impl.dart:144:23) E/flutter ( 2958): #10 GetQueue._check (package:get/get_utils/src/queue/get_queue.dart:42:47) E/flutter ( 2958): #11 GetQueue.add (package:get/get_utils/src/queue/get_queue.dart:29:5) E/flutter ( 2958): #12 GetStorage._addToQueue (package:get_storage/src/storage_impl.dart:139:18) E/flutter ( 2958): #13 Microtask.exec.<anonymous closure> (package:get_storage/src/storage_impl.dart:174:17) E/flutter ( 2958): #14 _microtaskLoop (dart:async/schedule_microtask.dart:40:21) E/flutter ( 2958): #15 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
原因
你在addStatus方法中把Firestore的DocumentReference对象(userstatus变量)直接写入了GetStorage,而GetStorage只支持存储可JSON序列化的数据类型(如Map、String、int等),DocumentReference是不可序列化的对象,因此触发序列化失败。
问题2:进入Profile页面触发NoSuchMethodError,热重载后消失
控制台报错:
======== Exception caught by widgets library ======================================================= The following NoSuchMethodError was thrown building Profile(dirty): Class '_JsonDocumentReference' has no instance method '[]'. Receiver: Instance of '_JsonDocumentReference' Tried calling: []("status") The relevant error-causing widget was: Profile Profile:file:///D:/FIVERR%20PROJECTS%20FLUTTER/helping_hand/helping_hand/lib/drawers/Slidedrawer.dart:22:20 When the exception was thrown, this was the stack: #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:38:5) #1 Profile.build (package:helping_hand/UI/Other/Profile.dart:65:120) #2 StatelessElement.build (package:flutter/src/widgets/framework.dart:4949:49) #3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4878:15) #4 Element.rebuild (package:flutter/src/widgets/framework.dart:4604:5) #5 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4859:5) #6 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4853:5) ... Normal element mounting (275 frames)
原因
因为GetStorage中存储的是DocumentReference对象,你在Profile页面尝试用['status']这个Map的操作符去访问它的属性,而DocumentReference根本没有这个方法,所以报错。热重载后暂时消失是因为缓存被重置,但问题根源未解决。
修复方案
核心修改:不要存储Firestore的引用对象,直接存储需要的状态数据
修改BarController.dart中的addStatus方法
把写入GetStorage的对象从DocumentReference改成传入的userStatus Map:
// status Future<void> addStatus(Map<String,String> userStatus) async { loadingbar(); try{ final DocumentReference userstatus= FirebaseFirestore.instance .collection('users') .doc(Auth().currentuser?.email); await userstatus.update({ "status":userStatus['status'],"description":userStatus['description'], }); // 原代码:Userbox.write('userStatus', userstatus); // 修改为:直接存储userStatus这个可序列化的Map Userbox.write('userStatus', userStatus); }catch(e){ if (kDebugMode) { print('add status error ::: $e'); } Get.snackbar('error','we have encountered an error'); } loadingbaroff(); } bool isloading = false; void loadingbar() { isloading = true; update(); } void loadingbaroff() { isloading = false; update(); }
验证Profile页面
修改后,Profile页面的代码不需要改动,因为现在GetStorage中存储的是Map<String,String>类型的数据,可以正常用['status']和['description']访问属性:
Container( alignment: Alignment.centerLeft, padding: const EdgeInsets.only(top: 24,bottom: 12,left: 24,right: 12), child: Text('User status : ${Userbox.read('userStatus') == null? 'not fetched':Userbox.read('userStatus')['status']}', style: const TextStyle(color: Colors.redAccent,fontWeight: FontWeight.normal,fontSize: 16),),), Container( alignment: Alignment.centerLeft, padding: const EdgeInsets.only(top: 24,bottom: 12,left: 24,right: 12), child: Text('status description : ${Userbox.read('userStatus')== null?'not fetched':Userbox.read('userStatus')['description']}', style: const TextStyle(color: Colors.redAccent,fontWeight: FontWeight.normal,fontSize: 16),),),
内容的提问来源于stack exchange,提问作者Abhiram
相关产品推荐
相关产品推荐

