flutterfirebasegoogle-cloud-firestoreflutter-streambuilder

Flutter error : Failure to access data inside a snapshot fetched from Firebase Firestore


Using Flutter 3.3.9, I fetch a record from my Firestore database using a Streambuilder. I use the following code segment to do this:

              StreamBuilder<Object>(
                stream: FirebaseFirestore.instance
                    .collection('users')
                    .doc(userId)
                    .snapshots(),
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return Text('Loading...');
                  }
                  return Text(
                    snapshot.data!.doc['username'], // This line is marked as error bexcause "doc" is illegal.
                    ),
                  );
                },
              ),

The snapshot.data!.doc['username'] gives the following error:

The getter 'doc' isn't defined for the type 'Object'.

I verified that the 'Object' is of type "AsyncSnapshot" (=snapshot.runtimeType). It looks like the only getters available for the snapshot.data are hashCode, runtimeType, toString(), and noSuchMethod(..).

I tried

snapshot.data!().doc['username'],

But this does not work either. The error is "The expression doesn't evaluate to a function, so it can't be invoked"

I was able to access the data without using the StreamBuilder. The following works:

                  final docRef = FirebaseFirestore.instance
                      .collection('users')
                      .doc(userId);

                  docRef.get().then(
                    (DocumentSnapshot doc) {
                      final data = doc.data() as Map<String, dynamic>;
                      print(data['username']);
                    },
                    onError: (e) => print("Error getting document: $e"),
                  );


Solution

  • you have two mistakes, in your piece of code, you should specify the type of the AsyncSnapshot, like this:

     StreamBuilder<DocumentSnapshot>( // Specified type
                    stream: FirebaseFirestore.instance
                        .collection('users')
                        .doc(userId)
                        .snapshots(),
                    builder: (context, AsyncSnapshot<DocumentSnapshot>  snapshot) { //Specified type
        //...
    

    now using snapshot.data!, it should be a DocumentSnapshot type, and as I see, that you're trying to get the data of that document so you need also to change this line:

      snapshot.data!.doc['username'],
    

    to this:

    (snapshot.data!.data() as Map<String, dynamic>)['username'],
    

    now it will access the username field properly.