Home > Enterprise >  Flutter Firestore how to convert document content to stream
Flutter Firestore how to convert document content to stream

Time:12-16

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>
    );
  • Related