Flutter Firestore 实时分页使用多个监听流合并
Flutter Firestore real-time pagination using multiple listeners streamed combined
我想使用 Bloc 从 Firestore 数据库创建分页屏幕。屏幕应随文档更改而更新。
我的 FirestoreProviderApi
收到来自 Bloc 单元的提取请求。从 Firestore 获取文档后,它使用 Stream
.
将它们发送回 Bloc
FirestoreProviderApi
:
final _pollOverviewStreamController = BehaviorSubject<QuerySnapshot>();
@override
Stream<QuerySnapshot> getOverviewPolls<QuerySnapshot>() =>
_pollOverviewStreamController.asBroadcastStream().cast();
@override
Future<void> fetchFirstOverviewPolls() async {
_overviewPollsRef.limit(5).snapshots().listen((querySnapshot) {
_pollOverviewStreamController.add(querySnapshot);
});
}
@override
Future<void> fetchNextOverviewPolls() async {
if (_pollOverviewStreamController.value.docs.isEmpty) return;
final lastDoc = _pollOverviewStreamController.value.docs.last;
_overviewPollsRef
.startAfterDocument(lastDoc)
.limit(5)
.snapshots()
.listen((querySnapshot) {
_pollOverviewStreamController.add(querySnapshot);
});
}
关于文档更改,我想更新我的文档列表。
现在,每当发生更改时,都会将新的 QuerySnapshot 附加到流中(而不是替换旧的)。
有没有办法将多个侦听器组合到同一个流中,只聚合最新的数据?
问题已解决。
我找到了关于如何实施的很好的文档real-time pagination using Firestore(已经实施了,效果很好)。
Youtube 实施:Flutter and Firestore real-time Pagination.
High-level 步数:
- 创建一个class-scoped文档列表状态变量。
- 每次都流式传输整个列表。
- 监听并迭代快照更改,update/add 文档到主列表。
- 如果列表不为空,则从列表中的最后一个 文档中获取。
我的实现:
final List<DocumentSnapshot> _overviewPolls = [];
@override
Future<void> fetchOverviewPolls(
[int firstFetchLimit = 1, int nextFetchLimit = 1]) async {
Query overviewPollsQuery = _overviewPollsRef.limit(firstFetchLimit);
if (_overviewPolls.isNotEmpty) {
overviewPollsQuery = overviewPollsQuery
.startAfterDocument(_overviewPolls.last)
.limit(nextFetchLimit);
}
overviewPollsQuery.snapshots().listen((querySnapshot) {
if (querySnapshot.docs.isNotEmpty) {
for (final doc in querySnapshot.docs) {
int index = _overviewPolls.indexWhere((d) => d.id == doc.id);
// if already exists - update poll
if (index >= 0) {
_overviewPolls[index] = doc;
}
// if new document - add poll
else {
_overviewPolls.add(doc);
}
}
_pollOverviewStreamController.add(_overviewPolls);
}
});
}
使用 orderBy
请注意,如果您在查询快照时使用 orderBy
,对订单字段的任何更新 都会导致整个列表重新排序 个项目。此外,在某些情况下,它会自动获取更多项目(因为我们对每个快照使用限制,并且项目列表重新排序,一些快照可能需要获取更多项目以填补其限制)。
我想使用 Bloc 从 Firestore 数据库创建分页屏幕。屏幕应随文档更改而更新。
我的 FirestoreProviderApi
收到来自 Bloc 单元的提取请求。从 Firestore 获取文档后,它使用 Stream
.
FirestoreProviderApi
:
final _pollOverviewStreamController = BehaviorSubject<QuerySnapshot>();
@override
Stream<QuerySnapshot> getOverviewPolls<QuerySnapshot>() =>
_pollOverviewStreamController.asBroadcastStream().cast();
@override
Future<void> fetchFirstOverviewPolls() async {
_overviewPollsRef.limit(5).snapshots().listen((querySnapshot) {
_pollOverviewStreamController.add(querySnapshot);
});
}
@override
Future<void> fetchNextOverviewPolls() async {
if (_pollOverviewStreamController.value.docs.isEmpty) return;
final lastDoc = _pollOverviewStreamController.value.docs.last;
_overviewPollsRef
.startAfterDocument(lastDoc)
.limit(5)
.snapshots()
.listen((querySnapshot) {
_pollOverviewStreamController.add(querySnapshot);
});
}
关于文档更改,我想更新我的文档列表。
现在,每当发生更改时,都会将新的 QuerySnapshot 附加到流中(而不是替换旧的)。 有没有办法将多个侦听器组合到同一个流中,只聚合最新的数据?
问题已解决。
我找到了关于如何实施的很好的文档real-time pagination using Firestore(已经实施了,效果很好)。
Youtube 实施:Flutter and Firestore real-time Pagination.
High-level 步数:
- 创建一个class-scoped文档列表状态变量。
- 每次都流式传输整个列表。
- 监听并迭代快照更改,update/add 文档到主列表。
- 如果列表不为空,则从列表中的最后一个 文档中获取。
我的实现:
final List<DocumentSnapshot> _overviewPolls = [];
@override
Future<void> fetchOverviewPolls(
[int firstFetchLimit = 1, int nextFetchLimit = 1]) async {
Query overviewPollsQuery = _overviewPollsRef.limit(firstFetchLimit);
if (_overviewPolls.isNotEmpty) {
overviewPollsQuery = overviewPollsQuery
.startAfterDocument(_overviewPolls.last)
.limit(nextFetchLimit);
}
overviewPollsQuery.snapshots().listen((querySnapshot) {
if (querySnapshot.docs.isNotEmpty) {
for (final doc in querySnapshot.docs) {
int index = _overviewPolls.indexWhere((d) => d.id == doc.id);
// if already exists - update poll
if (index >= 0) {
_overviewPolls[index] = doc;
}
// if new document - add poll
else {
_overviewPolls.add(doc);
}
}
_pollOverviewStreamController.add(_overviewPolls);
}
});
}
使用 orderBy
请注意,如果您在查询快照时使用 orderBy
,对订单字段的任何更新 都会导致整个列表重新排序 个项目。此外,在某些情况下,它会自动获取更多项目(因为我们对每个快照使用限制,并且项目列表重新排序,一些快照可能需要获取更多项目以填补其限制)。