Reputation: 343
I use BLoC logic to listen to my streams and I'd like to minimize data reads.
I understood that QuerySnapshot keeps track of previous documents and picks from cache if the document did not change.
The issue is that the snapshot doesn't contain information about the user's profile picture, name, etc. which i have to fetch using getInfoFromId(), and i would like to find a way not to use this function for every user when one user got changed, deleted or added
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();
}
);
}
And here is how my BLoC listens to the data
Stream<RoleState> _mapRolesToState() async* {
subscription?.cancel();
subscription =
_feedRepository.rolesToStream(globalNews.feedId).listen((data) {
add(RoleUpdated(data));
});
}
And here is how i change my roles
void changeRole(String idFeed,String userId, AppRole role){
collectionReference
.document(idFeed)
.collection('users')
.document(userId)
.updateData({
'role':EnumToString.parse(role),
});
}
My issue is the following : Anytime I am changing the role of a user, every other users get re-read by the stream and i have no clue how to fix it. Thanks in advance for the help.
Possibles states:
Possible events :
Here is the log after loading for the first time :
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 }
And after changing role :
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 }
After removing a member (Correctly deleted a member but still read info in the database):
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 }
Upvotes: 0
Views: 959
Reputation: 317382
If you want to read from the client local cache first before querying the server, you can do that to avoid reads. Just specify a source option to query the cache first, then if it's not there, query the server. Read more about Firestore persistence.
Upvotes: 2