Flutter中Future<List<List>>返回空数组问题排查求助
问题分析与修复方案
你的代码返回空列表[[], []],核心问题大概率出在对象相等性判断和冗余异步逻辑上,以下是具体修复点:
1. 移除不必要的Future.value()包装
async函数本身会自动返回Future,无需手动用Future.value()包装返回值,直接返回数据即可:
Future<List<QueryDocumentSnapshot>> getUserDocs() async { final userRef = FirebaseFirestore.instance.collection('users'); final QuerySnapshot result = await userRef.get(); return result.docs; } Future<List<QueryDocumentSnapshot>> getPostDocs() async { List<QueryDocumentSnapshot> userDocs = await getUserDocs(); List<QueryDocumentSnapshot> postsDocs = []; for (final resultValue in userDocs) { final postsRef = FirebaseFirestore.instance .collection('users') .doc(resultValue.id) .collection('posts'); final QuerySnapshot postsResult = await postsRef.get(); postsDocs.addAll(postsResult.docs); // 用addAll替代循环add,更高效 } return postsDocs; }
2. 修复对象相等性判断逻辑
你用!postsList.contains(post)和usersList.where((u) => u.uid == user.uid).toList().isEmpty判断重复,但默认的contains比较对象引用,若未重写==和hashCode,即使内容相同也会被判定为不同对象,导致数据无法正常加入列表。
重写Post类的相等性方法
假设用uid和date作为Post的唯一标识,在Post类中添加:
class Post { // ... 现有字段与fromJson方法 @override bool operator ==(Object other) => identical(this, other) || other is Post && runtimeType == other.runtimeType && uid == other.uid && date == other.date; @override int get hashCode => uid.hashCode ^ date.hashCode; }
优化列表添加逻辑
用any直接判断是否存在,避免依赖默认的contains行为:
// 替换原postsList循环 for (var postsMap in postsDocs) { final post = Post.fromJson(postsMap.data() as Map<String, dynamic>); if (!postsList.any((p) => p.uid == post.uid && p.date == post.date)) { postsList.add(post); } } // 替换原usersList循环 for (final value in userDocs) { final profileInfo = ProfileInfoObject.fromJson(value.data() as Map<String, dynamic>); final userPosts = postsList.where((p) => p.uid == value.id).toList(); Profile profile = Profile(profileInfo, userPosts); UserSearchResult user = UserSearchResult(profile, value.id); if (!usersList.any((u) => u.uid == user.uid)) { usersList.add(user); print('usersList: $usersList'); } }
3. 避免重复请求Firestore
fetchUsersAndPosts中先调用getUserDocs(),getPostDocs()内部又重复调用一次,造成资源浪费。修改getPostDocs接收已获取的userDocs参数:
// 修改getPostDocs,接收外部传入的userDocs Future<List<QueryDocumentSnapshot>> getPostDocs(List<QueryDocumentSnapshot> userDocs) async { List<QueryDocumentSnapshot> postsDocs = []; for (final resultValue in userDocs) { final postsRef = FirebaseFirestore.instance .collection('users') .doc(resultValue.id) .collection('posts'); final QuerySnapshot postsResult = await postsRef.get(); postsDocs.addAll(postsResult.docs); } return postsDocs; } // 在fetchUsersAndPosts中复用已获取的userDocs Future<List> fetchUsersAndPosts() async { List<QueryDocumentSnapshot> userDocs = await getUserDocs(); List<QueryDocumentSnapshot> postsDocs = await getPostDocs(userDocs); // ... 后续转换逻辑不变 }
4. 排查基础问题
若修复后仍为空,检查:
- Firestore安全规则是否允许当前用户读取
users和users/{uid}/posts集合 - 确认Firestore中存在对应数据,且字段名与
fromJson解析的字段完全匹配(注意大小写)
内容的提问来源于stack exchange,提问作者Globe
相关产品推荐
相关产品推荐

