在加载 Firebase 快照时使用 Flutter 中的 Bloc 流式等待和阻止其他事件
Posted
技术标签:
【中文标题】在加载 Firebase 快照时使用 Flutter 中的 Bloc 流式等待和阻止其他事件【英文标题】:Stream waiting and blocking other events using Bloc in Flutter while loading Firebase snapshots 【发布时间】:2019-08-11 13:04:13 【问题描述】:我正在使用 Flutter、Firebase Firestore 和 bloc 模式编写应用程序。
当应用程序打开时,我想从 firestore 数据库中加载一些书籍,为此我定义了以下 bloc 代码:
class EditorBloc extends Bloc<BookEvent, BooksState>
@override
BooksState get initialState => BooksLoading();
EditorBloc();
Stream<BooksState> _loadBooks() async*
final CollectionReference bookPostRef = Firestore.instance.collection('books');
try
Stream<QuerySnapshot> stream = bookPostRef.snapshots();
await for (QuerySnapshot querySnapshot in stream)
List<Book> remoteBooks = List();
for (var documentSnapshot in querySnapshot.documents)
remoteBooks.add(Book.fromDocumentSnapshot(documentSnapshot));
yield BooksLoaded(remoteBooks);
// If I return here I can dispatch more events but not all the snapshots will be processed
catch (_)
yield BooksNotLoaded();
Stream<BooksState> _saveBooks(Gym gym, Sector sector, BookHistory booksHistory) async*
// Some code
Stream<BooksState> _addBooks(Gym gym, Sector sector, BookHistory booksHistory) async*
// Some code
@override
Stream<BooksState> mapEventToState(BooksState currentState, BookEvent event) async*
if (event is LoadBooks)
yield* _loadBooks(event.gym, event.sector);
else if(event is SaveBooks)
yield BooksLoading();
yield* _saveBooks(event.gym, event.sector, event.booksHistory);
else if (event is AddBook)
yield* _addBooks(gym, sector, booksHistory)
当应用程序启动时,我使用以下代码加载书籍集合:
myBloc.dispatch(LoadBooks());
当书籍加载时我会收到通知,但如果我发送类似这样的其他事件:
myBloc.dispatch(AddBook(newBook));
该事件永远不会被处理,因为EditorBloc
仍在等待方法_loadBooks
中的其他快照。
我应该怎么做才能调度其他事件?
谢谢!
【问题讨论】:
你是故意监听LoadBooks
的变化吧?
是的,可以吗?不知道该怎么走
我遇到了同样的问题,不得不将我的查询从 ref.snapshots()
更改为 List<DocumentSnapShot> snapshots = await ref.get()
以获得未来。然后我使用了yield MyState(snapshots.map((snapshot) => myObject(snapshot)).toList());
你已经解决了吗?
@JoanP.S 你能发布详细的代码来展示你找到的解决方案吗?
【参考方案1】:
解决此问题的一种方法是在 Future 中收听 Stream。一旦该 Future 完成,您就可以开始其他事件。
Future<bool> whenFinishLoading(Stream<BooksState> source) async
await for (value in source)
// Define a condition expecting a value from Stream
if (value)
return value;
return false;
然后您可以使用 Future whenFinishLoading(Stream<BookState>)
等待它完成以开始下一个 Stream 事件。
【讨论】:
以上是关于在加载 Firebase 快照时使用 Flutter 中的 Bloc 流式等待和阻止其他事件的主要内容,如果未能解决你的问题,请参考以下文章
UITableView 未加载 Firebase 快照数据。
Firebase Firestore get() 快照在第二次查询时冻结
在 Flutter 中从 Firebase FireCloud 接收数据时,StreamBuilder 中的快照代码不会被执行