Flutter & Firebase 将 10 多个 Firebase 文档放入 Stream<List<Map>>
Posted
技术标签:
【中文标题】Flutter & Firebase 将 10 多个 Firebase 文档放入 Stream<List<Map>>【英文标题】:Flutter & Firebase Get more than 10 Firebase Documents into a Stream<List<Map>> 【发布时间】:2021-05-17 07:50:30 【问题描述】:使用 Flutter 和 Firestore,我试图将 10 多个文档放入 Stream。我可以使用映射 QuerySnapshot 的集合上的 .where 子句来做到这一点。但是,10 个限制是一个杀手。
我在我的应用程序中使用提供程序包。因此,在 Flutter 中使用 StreamProvider 构建流时,我可以返回一个
- StreamStreamStream
我需要介于 1 和 2 之间的东西。
我有一个包含多达 500 个文档的集合,用户可以选择这 500 个文档的任意组合进行查看。用户组装班级名册以查看他们的用户列表。
所以我正在寻找一种方法来获取单个流,例如 30 个文档,然后将它们编译成一个列表:但我需要这个 List 所以,我目前的努力: 感觉我在下面作弊:如果我将快照直接放在上面的 Stream thisStream 中,我会收到等待错误,因为如果我等待,Stream 就不是未来,如果我不等待,它会移动得太快并得到一个空错误。 我如何在 _teacherRosterListFromSnapshot 中映射的示例(这里没有任何问题): 我的 StreamProvider 逻辑和错误: 错误:参数类型“Future AttendeeData 是我的地图类名称。 所以,问题总结: 我可以使用 StreamProvider 的另一种方法获取数据,但它的行为不像 Stream 并且状态没有更新。我希望把它放到 Provider 中,因为我在那里很舒服,而且我可以很容易地管理状态。但是,乞丐不能挑剔。 Future<Stream<List<AttendeeData>>> getStreams() async
List<Stream<AttendeeData>> getStreamsOutput = [];
for (var i = 0; i < teacherRosterList.length; i++)
Stream thisStream = await returnTeacherRosterListStream(facility, teacherRosterList[i]);
getStreamsOutput.add(thisStream);
return StreamZip(getStreamsOutput).asBroadcastStream();
Future<Stream<AttendeeData>> returnTeacherRosterListStream(String thisFacility, String thisID) async
return facilityList.doc(thisFacility).collection('attendance').doc(thisID).snapshots().map(_teacherRosterListFromSnapshot);
AttendeeData _teacherRosterListFromSnapshot(DocumentSnapshot doc)
// return snapshot.docs.map((doc)
return AttendeeData(
id: doc.data()['id'] ?? '',
authorCreatedUID: doc.data()['authorCreatedUID'] ?? '',
);
return MultiProvider(
providers: [
StreamProvider<List<AttendeeData>>.value(
value: DatabaseService(
teacherRosterList: programList,
facility: user.claimsFacility,
).getStreams()),
]
我什至可以这样做吗?我基本上是在流式传输地图流列表......这是一回事吗?
如果可以,我该怎么做?
一种。我无法将它放入 StreamProvider,因为 getStreams 是 Future...我该如何克服这个问题?
【问题讨论】:
【参考方案1】:我自己解决了这个问题,由于缺乏良好的开始和结束的答案,我为追随我的可怜的灵魂提供了我的例子,他们试图自己学习这些东西。我是初学者,所以这是一个艰难的过程:
目标: 您在集合中有任意数量的文档,并且您希望按文档编号提交任意数量的文档列表,并返回这些映射文档列表的单个流。您想要超过 10 个(对 .where 查询的 Firestore 限制),少于所有文档......所以介于 QuerySnapshot 和 DocumentSnapshot 之间。
解决方案:我们将获得一个 QuerySnapshot 列表,我们将组合它们并映射它们并将它们作为单个流输出。所以我们得到了 10 个块(最大值),然后剩下一些奇数。我将我的插入到一个 Provider 中,这样我就可以随时随地获得它。
所以从我的提供者那里,我将其称为 Stream 值:
Stream<List<AttendeeData>> filteredRosterList()
var chunks = [];
for (var i = 0; i < teacherRosterList.length; i += 10)
chunks.add(teacherRosterList.sublist(i, i + 10 > teacherRosterList.length ? teacherRosterList.length : i + 10));
//break a list of whatever size into chunks of 10.
List<Stream<QuerySnapshot>> combineList = [];
for (var i = 0; i < chunks.length; i++)
combineList.add(*[point to your collection]*.where('id', whereIn: chunks[i]).snapshots());
//get a list of the streams, which will have 10 each.
CombineLatestStream<QuerySnapshot, List<QuerySnapshot>> mergedQuerySnapshot = CombineLatestStream.list(combineList);
//now we combine all the streams....but it'll be a list of QuerySnapshots.
//and you'll want to look closely at the map, as it iterates, consolidates and returns as a single stream of List<AttendeeData>
return mergedQuerySnapshot.map(rosterListFromTeacherListDocumentSnapshot);
以下是我如何映射它以供您参考(为简洁起见,删除了所有字段):
List<AttendeeData> rosterListFromTeacherListDocumentSnapshot(List<QuerySnapshot> snapshot)
List<AttendeeData> listToReturn = [];
snapshot.forEach((element)
listToReturn.addAll(element.docs.map((doc)
return AttendeeData(
id: doc.data()['id'] ?? '',
authorCreatedUID: doc.data()['authorCreatedUID'] ?? '',
);
).toList());
);
return listToReturn;
【讨论】:
以上是关于Flutter & Firebase 将 10 多个 Firebase 文档放入 Stream<List<Map>>的主要内容,如果未能解决你的问题,请参考以下文章
Flutter & Firebase - Firebase Analytics setUserProperty for Anonymous users
Flutter & Firebase:如何检查某个项目是不是存在于 Firebase 文档中的数组中
Flutter & firebase - StreamBuilder 未加载
Flutter 2 - firebase_remote_config 0.6.0 & firebase_core ^0.7.0 版本冲突