I have a single document in Firestore, which holds a map of chat messages:
'a': { 'sentAt': '...', 'content': '...' },
'b': { 'sentAt': '...', 'content': '...' },
'c': { 'sentAt': '...', 'content': '...' },
I want to create a Firestore Service which listens to changes in that document (a new message added for example) and returns a stream of messages (Map<String, MessageModel>) like so:
Stream<Map<String, MessageModel>> getMessagesStream() {
return _firestore
.collection('chats')
.doc('chat')
.snapshots()
.map((snapshot) =>
???
);
}
How can I achieve that (what should be insted of the ??? there)?
This doesn't work:
(snapshot.data() as Map)
.cast<String, dynamic>()
.forEach((key, value) {
key: MessageModel.fromJson(value);
})
EDIT: Seems like this does the job:
Stream<Map<String, MessageModel>> getMessagesStream() {
return _firestore
.collection('chats')
.doc('chat')
.snapshots()
.asyncMap((snapshot) => {
for (var message in (snapshot.data() as Map).entries)
message.key:
MessageModel.fromJson(message.value)
});
}
Still not sure what is the difference between .map and .asyncMap though...
Also love to hear your thoughts about this approach (Firestore as a service etc.)
CodePudding user response:
What you're looking for is asyncMap
https://api.flutter.dev/flutter/dart-async/Stream/asyncMap.html
Stream<Map<String, MessageModel>> getMessagesStream() {
return _firestore
.collection('chats')
.doc('chat')
.snapshots()
.asyncMap((snapshot) =>
// Convert your snapshot to Map<String, MessageModel>
);