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

Stream返回空列表但所有打印语句均正常输出的问题排查

问题分析与修复方案

你的问题核心是异步执行顺序错误,导致返回Stream时retVal还没被填充数据:

  • rooms.forEach是异步遍历Firestore的Stream事件,而getOtherUser又是异步请求,你在这些异步操作还没完成时就直接返回了Stream.value(retVal),此时retVal还是空数组。
  • 另外,Firestore的snapshots()本身就是一个Stream,你应该直接转换这个Stream,而不是手动遍历后返回静态Stream。

修改方案

用asyncMap处理Firestore的snapshot流,确保每个snapshot对应的所有异步请求完成后,再把处理好的列表发射到Stream中:

Stream<List<RoomsListModel>>? roomsListStream() {
  try {
    print("userId: $userId");
    // 直接返回转换后的Firestore snapshot流
    return FirebaseFirestore.instance
        .collection("rooms")
        .where("users", arrayContains: userId)
        .orderBy("latestMessageTime", descending: true)
        .snapshots()
        .asyncMap((snapshot) async {
      List<RoomsListModel> retVal = [];
      // 遍历当前snapshot的所有文档,等待每个getOtherUser请求完成
      for (var doc in snapshot.docs) {
        print("element: $doc");
        var room = doc.data();
        print("room: $room");
        var roomId = room["roomId"];
        var otherUserId = room["users"].firstWhere((element) => element != userId);
        var lastMessage = room["latestMessage"];
        var lastMessageTime = room["latestMessageTime"];
        print("otherUserId: $otherUserId");
        
        // 用await等待异步请求完成,确保数据被添加到retVal
        var value = await getOtherUser(otherUserId);
        print("value: $value");
        var avatar = value["photoUrl"];
        var name = value["name"];
        retVal.add(RoomsListModel(
          roomId: roomId,
          otherUserId: otherUserId,
          avatar: avatar,
          name: name,
          lastMessage: lastMessage,
          lastMessageTime: lastMessageTime,
        ));
      }
      // 所有文档处理完成后,返回填充好的列表
      return retVal;
    });
  } catch (e) {
    print("Error: $e");
    return null;
  }
}

关键修改点

  • 用asyncMap替代原有的forEach,这样能把每个Firestore snapshot转换成异步处理后的列表。
  • 把forEach换成for循环并使用await,确保每个getOtherUser请求完成后再处理下一个文档,保证retVal被正确填充。
  • 直接返回转换后的Firestore Stream,而不是创建一个静态的Stream.value(retVal)。

这样修改后,Stream会在每次Firestore数据更新时,自动发射处理完成的RoomsListModel列表,你就能正常访问到数据了。

内容的提问来源于stack exchange,提问作者cipano

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 11:40:29