Flutter Firebase使用Stream时List<Future<Item>>类型不匹配报错
问题根因
你的getMessagedata是异步方法,返回Future<MessageModel>类型,直接对文档列表做map操作后得到的是List<Future<MessageModel>>,和方法要求返回的List<MessageModel>类型不匹配。同时Stream的普通map方法不会等待异步操作完成,无法处理你需要的异步转换逻辑。
解决方案
需要同时做两处修改:使用asyncMap处理Stream的异步转换,搭配Future.wait批量等待所有异步任务完成。
修改后的代码如下:
Stream<List<MessageModel>> getMessages() { Stream<QuerySnapshot> snap = FirebaseFirestore.instance .collection('messages') .doc(groupChatId) .snapshots(); return snap.asyncMap((event) async { // Future.wait 会等待列表中所有Future执行完成,返回对应的结果列表 return await Future.wait( event.docs.map((doc) => MessageModel.getMessagedata(doc)), ); }); }
如果你偏好async* + yield的写法,也可以用下面的等价实现:
Stream<List<MessageModel>> getMessages() async* { Stream<QuerySnapshot> snap = FirebaseFirestore.instance .collection('messages') .doc(groupChatId) .snapshots(); await for (final event in snap) { final messages = await Future.wait( event.docs.map((doc) => MessageModel.getMessagedata(doc)), ); yield messages; } }
修改说明
asyncMap是Stream提供的专门用于异步转换的方法,允许转换逻辑返回Future,会等待Future完成后再向下游发送事件Future.wait接收一个Future列表作为入参,会并行执行所有Future,待全部完成后返回统一的结果列表,刚好可以把List<Future<MessageModel>>转为你需要的List<MessageModel>- 你之前尝试给单个map回调加
async/await的写法没有生效,是因为仅给单个元素的回调加异步,还是会返回Future类型的元素,没有统一等待整个列表的所有异步任务完成,所以类型依然不匹配
内容的提问来源于stack exchange,提问作者RyanBuss01
相关产品推荐
相关产品推荐

