Flutter中Firestore get()返回null:ID可获取但数据为空
Flutter Firestore get() 返回null:文档ID存在但对象属性为空
问题现象
调用Firestore的get()方法时,Firestore中确实存在目标文档,控制台能正常打印文档ID(senderLast、receiverLast),但通过PetUser.fromJson解析后,senderL和receiverL的name、imageUrl属性始终为null。
问题根源
- 异步执行顺序混乱:
initState中同时调用三个异步方法,getReceiverProfile和getSenderProfile会在getUpdatedChatterPro完成前执行,此时senderLast和receiverLast还未被正确赋值,导致查询用的文档ID无效,无法获取正确数据。 - debugPrint时机过早:
debugPrint是同步代码,在所有异步操作完成前就触发,此时senderL和receiverL还是初始空对象,属性自然为null。 - async/await与then混用:混合两种异步写法导致流程控制模糊,增加逻辑出错概率。
解决方案
1. 保证异步操作的依赖顺序
让获取用户信息的方法在getUpdatedChatterPro完成后再执行,确保senderLast和receiverLast已正确赋值。
2. 统一异步代码风格
优先使用async/await替代then,让逻辑更清晰。
3. 增加空值与文档存在性判断
避免无效查询和空指针异常。
修正后的代码
PetUser senderL = PetUser(); PetUser receiverL = PetUser(); String? senderLast; String? receiverLast; // 初始化null,避免空字符串隐患 getUpdatedChatterPro() async { final snaps = await ServerAPI() .chatsCollection .doc(widget.id) .collection('messages') .orderBy('time', descending: false) .limitToLast(1) .get(); if (snaps.docs.isNotEmpty) { setState(() { senderLast = snaps.docs.last['senderId']; receiverLast = snaps.docs.last['receiverId']; }); // 确保ID赋值后再查询用户信息 await getReceiverProfile(); await getSenderProfile(); // 所有异步操作完成后再打印 debugPrint( '${widget.id}, $senderLast, $receiverLast, ${senderL.imageUrl}, ${senderL.name}, ' '${receiverL.name}, ${receiverL.imageUrl}' ); } } getReceiverProfile() async { if (receiverLast == null) return; final docSnapshot = await FirebaseFirestore.instance .collection('users') .doc(receiverLast) .get(); if (docSnapshot.exists) { setState(() { receiverL = PetUser.fromJson(docSnapshot.data()!); }); } } getSenderProfile() async { if (senderLast == null) return; final docSnapshot = await FirebaseFirestore.instance .collection('users') .doc(senderLast) .get(); if (docSnapshot.exists) { setState(() { senderL = PetUser.fromJson(docSnapshot.data() as Map<String, dynamic>); }); } } @override void initState() { super.initState(); // 仅调用第一个方法,后续逻辑在其内部触发 getUpdatedChatterPro(); }
额外检查点
- 确认
PetUser.fromJson方法的字段映射与Firestore文档的字段名完全一致(比如Firestore存的是name,fromJson里不能写成userName)。 - 检查Firestore的安全规则,确保当前用户有权限读取
users集合的文档。
内容的提问来源于stack exchange,提问作者HaKim
相关产品推荐
相关产品推荐

