Closure: () => Map<String, dynamic> from Function 'data':

Viewed 5328

So im trying to stream data from firestore but when printing the data I get:

I/flutter ( 8356): Closure: () => Map<String, dynamic> from Function 'data':.

I am using this code to fetch the data:

 void messagesStream() async {
    Stream collectionStream = _firestore.collection('messages').snapshots();
    await for (var snapshot in collectionStream) {
      for (var message in snapshot.docs) {
        print(message.data());
      }
    }

When new data is added to the messages collection I get the Closure message so it is interacting with the databse.

What I want is it to print out the contents of the new document within the collection.

Any help is appreciated.

3 Answers

That's not the way you're supposed to iterate the results of a Stream. If you have a Stream and you want to process its results, you're supposed to use listen() to receive the results asynchronously.

Stream collectionStream = _firestore.collection('messages').snapshots();
collectionStream.listen((QuerySnapshot querySnapshot) {
    querySnapshot.documents.forEach((document) => print(document.data()));
}

See also: Firestore collection query as stream in flutter

You might also want to review the documentation to learn how to query Firestore in Flutter.

void getMessages() async {
   final messages= await _firestore.collection('messages').get();
   for(var message in messages.docs){
     print(message.data());

   }

this is working check this and call getMessages() wherever you wana call

I encountered the same issue with pretty much your exact same code (sans your Stream variable). My suggestion is to delete the Stream var altogether (I tested the code below and got it to print the data from the Firestore database) :

    void messagesStream() async {
    await for (var snapshot in _firestore.collection('messages').snapshots()) {
      for (var message in snapshot.docs) {
        print(message.data());
      }
    }
  }

Alternatively, try addding QuerySnapShot as the data type for your Stream variable (untested):

Stream<QuerySnapshot> collectionStream = _firestore.collection('messages').snapshots();

You could also replace the entire method by creating a new Stateless Widget (MessagesStream) that returns a StreamBuilder:

class MessagesStream extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: _firestore.collection('messages').snapshots(),
      builder: (context, snapshot) {
       final messages = snapshot.data.docs;
       for (var message in messages) {
       print(message.data());
 }

...and call it wherever you see fit while you test:

class _ChatScreenState extends State<ChatScreen> { (...)
body: Column(children: <Widget> [
//Just an example.
MessageStream(),
   ],
  ),
(...)
}

***Be sure you make the _fireStore (which should be a FirebaseFirestore.instance) a global variable if you're going with the Stateless Widget route.

Related