You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 15:30:55