Flutter从Firebase Realtime Database获取好友列表报错如何解决
问题原因排查
- 核心错误出在
User.fromJson(json.decode(userInfo.value))这行代码。Firebase Realtime Database 的DataSnapshot.value会自动把数据库里的JSON结构解析为Dart的Map/List类型,不需要再调用json.decode(该方法入参要求为JSON格式字符串,传入Map自然会报类型不匹配错误)。 - 其他潜在问题:
- 没有做空校验,如果
event.snapshot.value为空(用户还没有好友),直接转Map会抛异常 - 用
forEach嵌套异步请求,无法监听所有好友数据加载完成的时机,后续无法正常更新UI - 没有在State销毁时取消数据库监听,存在内存泄漏风险
- 没有做空校验,如果
修复后代码
class _FriendsScreenState extends State<FriendsScreen> { // 存储好友列表用于页面渲染 List<User> friendList = []; // 保存数据库监听订阅,用于销毁时取消 StreamSubscription? _friendSubscription; @override void initState() { super.initState(); getUserFriendsList(); } @override void dispose() { _friendSubscription?.cancel(); super.dispose(); } void getUserFriendsList() { _friendSubscription = rtdb.child('friends').child(widget.currentUserID).onValue.listen((event) async { // 先清空旧的好友数据 friendList.clear(); // 快照空校验 if (event.snapshot.value == null) { if(mounted) setState(() {}); return; } // 转换数据类型 final data = Map<String, dynamic>.from(event.snapshot.value as Map); // 用for in替代forEach处理异步逻辑,保证所有请求完成后再更新UI for (String friendId in data.keys) { final userInfo = await usersRef.child(friendId).get(); if (userInfo.exists) { // 直接转换为Map,不需要调用json.decode final userMap = Map<String, dynamic>.from(userInfo.value as Map); final user = User.fromJson(userMap); friendList.add(user); } } // 加载完成后更新UI if(mounted) setState(() {}); }); } factory User.fromJson(Map<String, dynamic> parsedJson) { return User( imageUrl: parsedJson['userImageUrl'], userFirstName: parsedJson['userFirstName'], userLastName: parsedJson['userLastName'], userID: parsedJson['userID'], ); } }
内容的提问来源于stack exchange,提问作者Jackjak
相关产品推荐
相关产品推荐

