Firestore 和 Flutter:使用流优化数据读取
Posted
技术标签:
【中文标题】Firestore 和 Flutter:使用流优化数据读取【英文标题】:Firestore and flutter : Optimize data reads with streams 【发布时间】:2020-10-20 01:53:09 【问题描述】:说明
我使用 BLoC 逻辑来收听我的流,我想尽量减少数据读取。
我知道 QuerySnapshot 会跟踪以前的文档,如果文档没有更改,则会从缓存中挑选。
问题是快照不包含有关用户个人资料图片、姓名等的信息,我必须使用 getInfoFromId() 获取这些信息,我想找到一种方法不使用此函数 一个用户被更改、删除或添加时的每个用户
Stream<List<FeedUser>> rolesToStream(String newsId)
return Firestore.instance
.collection('pages')
.document(newsId).collection('users')
.snapshots()
.map(
(snapshot)
return snapshot.documents.map(
(document)
FeedUser user = FeedUser();
user.fromSnapshot(document);
user.contact = getInfoFromId(user.id);
// The contact infos of a user is a future because we have to get it elsewhere, in a Firebase (NOT FIRESTORE) database. It theorically shouldn't be read after being read once after the event "RoleLoadMembers"
// Then we retrieve the contact infos after it is retrieved
user.contact.then(
(contact)
user.retrievedContact = contact;
);
return user;
).toList();
);
这是我的 BLoC 监听数据的方式
Stream<RoleState> _mapRolesToState() async*
subscription?.cancel();
subscription =
_feedRepository.rolesToStream(globalNews.feedId).listen((data)
add(RoleUpdated(data));
);
这就是我如何改变我的角色
void changeRole(String idFeed,String userId, AppRole role)
collectionReference
.document(idFeed)
.collection('users')
.document(userId)
.updateData(
'role':EnumToString.parse(role),
);
我的问题如下:每当我更改用户的角色时,其他所有用户都会被流重新读取,我不知道如何解决它。 提前感谢您的帮助。
状态日志
可能的状态:
RoleLoadingMembers 角色加载成功 RoleLoadingFailure(从未发生过)可能发生的事件:
RoleLoadMembers 角色更新 更改角色 删除成员 添加成员这是第一次加载后的日志:
I/flutter (27792): RoleLoadMembers
I/flutter (27792): Reading infos of the user : E4nT23Ohi0Za7JIQDaQ7Ohwe7Rn1
I/flutter (27792): Reading infos of the user : Svbj4tAIhIRcjQNqvYYsLSDXxwu2
I/flutter (27792): Reading infos of the user : cBm2KG6rEAbiaLGMAC08bvefNSn1
I/flutter (27792): RoleUpdated
I/flutter (27792): Transition currentState: RoleMembersLoading, event: RoleUpdated, nextState: RoleLoadingSuccess
在换了角色之后:
I/flutter (27792): ChangeRole
I/flutter (27792): Reading infos of the user : E4nT23Ohi0Za7JIQDaQ7Ohwe7Rn1
I/flutter (27792): Reading infos of the user : Svbj4tAIhIRcjQNqvYYsLSDXxwu2
I/flutter (27792): Reading infos of the user : cBm2KG6rEAbiaLGMAC08bvefNSn1
I/flutter (27792): RoleUpdated
I/flutter (27792): Transition currentState: RoleLoadingSuccess, event: RoleUpdated, nextState: RoleLoadingSuccess
删除成员后(正确删除了成员但仍读取数据库中的信息):
I/flutter (27792): RemoveMember
I/flutter (27792): Reading infos of the user : E4nT23Ohi0Za7JIQDaQ7Ohwe7Rn1
I/flutter (27792): Reading infos of the user : Svbj4tAIhIRcjQNqvYYsLSDXxwu2
I/flutter (27792): RoleUpdated
I/flutter (27792): Transition currentState: RoleLoadingSuccess, event: RoleUpdated, nextState: RoleLoadingSuccess
【问题讨论】:
如果您不想重新阅读已经阅读过的文档,您可以实现自己的客户端缓存。 我把它作为最后的手段,因为我从来没有这样做过,但我会试一试,学习永远不会有坏处:)!祝你有美好的一天 【参考方案1】:如果您想在查询服务器之前先从客户端本地缓存中读取,您可以这样做以避免读取。只需指定source option 先查询缓存,如果不存在,则查询服务器。阅读有关Firestore persistence 的更多信息。
【讨论】:
以上是关于Firestore 和 Flutter:使用流优化数据读取的主要内容,如果未能解决你的问题,请参考以下文章
Flutter:使用来自 Firestore 的多集合流创建动态更新的 DataTable
将用户 uid 传递给 Flutter 中的 Firestore 流查询
Flutter/Firestore - 在流构建器中的动态列表视图上实现“分页”