Flutter中用自定义类创建多个Firebase StreamProvider流
解决方案
1. 修正自定义类
保留类的核心结构,建议给类起个语义明确的名字(比如MessagesSnapshot),避免模糊命名:
class MessagesSnapshot { final QuerySnapshot snapshot; MessagesSnapshot({required this.snapshot}); }
2. 修复流生成函数
你的核心问题是没有正确将Firestore返回的Stream<QuerySnapshot>转换为Stream<MessagesSnapshot>,同时函数内未生成任何流事件。修改后的函数如下:
Stream<MessagesSnapshot> getMessagesStreamSnapshot(BuildContext context) async* { try { final auth = Provider.of<AuthenticationService>(context, listen: false); final uid = await auth.getFormattedUID(); print("获取消息流中..."); // 获取Firebase chat集合的快照流 final chatStream = FirebaseFirestore.instance .collection('users') .doc(uid) .collection('chat') .snapshots(); // 遍历流中的每个快照,包装成自定义类后输出 await for (final snapshot in chatStream) { yield MessagesSnapshot(snapshot: snapshot); } } catch (error) { print(error); rethrow; // 可选:将错误抛给上层处理 } }
3. 配置MultiProvider
现在可以正常使用不同类型的StreamProvider,彻底解决类型冲突问题:
StreamProvider<QuerySnapshot>( create: (_) => getWeeksStreamSnapshot(_), // weeks集合流 ), StreamProvider<MessagesSnapshot>( create: (_) => getMessagesStreamSnapshot(_), // chat集合流 ),
4. 访问数据
在Widget中通过Provider获取自定义类实例,进而访问内部的QuerySnapshot:
// 获取自定义类实例 final messagesWrapper = Provider.of<MessagesSnapshot>(context); // 取出内部的QuerySnapshot final chatSnapshot = messagesWrapper.snapshot; // 根据你的Firebase结构,遍历chat集合中的文档并获取messages字段 for (var doc in chatSnapshot.docs) { final messages = doc.data()['messages']; // 处理messages数据 }
错误原因说明
你之前的代码直接将Firestore的Stream<QuerySnapshot>赋值给自定义类的snapshot字段(该字段需要单个QuerySnapshot实例,而非流),同时函数内未通过yield生成流事件,导致流没有任何输出。修改后通过await for监听Firestore流,将每个快照包装成自定义类后输出,就能正确生成Stream<MessagesSnapshot>。
内容的提问来源于stack exchange,提问作者Finn
相关产品推荐
相关产品推荐

