Flutter中如何基于Stream实现获取Firestore各文档下的子集合列表
实现思路
你需要同时监听两层数据的变动:主集合categories的文档增减变动、以及每个主文档下properties子集合的内容变动,这里通过流转换+多流合并实现:
- 用
snapshots()方法替代get()获取实时数据流,而非单次请求 - 主集合流触发时,为所有当前存在的主文档分别创建子集合的监听流
- 合并所有子集合的快照数据,统一转换为
Category列表输出,任意层级数据变动都会推送最新的完整列表
完整Stream实现代码
这里基于rxdart实现多流合并,如果你的项目还没有引入rxdart,先在pubspec.yaml中添加依赖:
dependencies: rxdart: ^0.27.7 # 可根据你的项目适配最新版本
对应方法实现:
import 'package:rxdart/rxdart.dart'; Stream<List<Category>> getPropertiesDocsStream() { // 第一步:监听categories主集合的实时快照 return _firebaseFirestore.collection('categories').snapshots() // 第二步:主集合变动时,重新生成所有子集合的监听流 .switchMap((mainSnapshot) { // 遍历所有当前主文档,为每个文档创建properties子集合的监听流 final subStreams = mainSnapshot.docs.map((mainDoc) { return mainDoc.reference.collection('properties').snapshots(); }).toList(); // 第三步:合并所有子集合的快照,统一转换为Category列表 return CombineLatestStream.list<QuerySnapshot>(subStreams) .map((subSnapshotsList) { List<Category> categoryList = []; for (var subSnapshot in subSnapshotsList) { for (var doc in subSnapshot.docs) { categoryList.add(Category.fromSnapShpt(doc)); } } return categoryList; }); }); }
组件使用说明
在Flutter组件中直接用StreamBuilder监听这个流即可,不需要手动触发刷新:
StreamBuilder<List<Category>>( stream: getPropertiesDocsStream(), builder: (context, snapshot) { if (snapshot.hasData) { final categories = snapshot.data!; // 渲染你的列表逻辑 return ListView.builder( itemCount: categories.length, itemBuilder: (context, index) => /* 你的列表项实现 */ ); } // 加载/错误状态处理 return const CircularProgressIndicator(); } )
这种实现下,即使你用AutomaticKeepAliveClientMixin保活组件,只要组件不被销毁,流会持续监听,数据变动时会自动更新UI,不会出现收不到变更的问题。
内容的提问来源于stack exchange,提问作者Mo7ammed 7amad
相关产品推荐
相关产品推荐

