Search code examples
fluttergoogle-cloud-firestoregetdata-retrieval

Error: Unhandled Exception: type 'Null' is not a subtype of type 'Map<String, dynamic>' in type cast


I am working with Flutter and I have added some data to a Firestore collection, and now I want to retrieve values from the collection which are relevant to the user logged in.

The method I have drafted for retrieving data is:

Future<void> discoverUser() async {
      FirebaseAuth _auth = FirebaseAuth.instance;
      final cDocRef = dB.collection('c/ubojjWZCZ/cDetails').doc('userAge');
      final pDocRef = dB.collection('p/sgujWHR5/pDetails').doc('userAge');
      try {
        if (_auth != null) {
         await cDocRef.get().then(
                  (DocumentSnapshot doc) async {
                final data = doc.data() as Map<String, dynamic>;
                if (doc != null) {
                  userAge = data['userAge'];
                  if (userAge < 20) {
                    await pDocRef.get().then((DocumentSnapshot doc) {
                      final data = doc.data() as Map<String, dynamic>;
                      if (doc != null) {
                        userAge = data['userAge'];
                      }
                    },
                    onError: (e) => print('Error getting document $e'),
                    );
                  }
                }
              },
              onError: (e) => print('Error getting document $e'),
      );
        }
      } on Exception catch (e) {
        print(e);
      }
    }

The error message from Flutter is:

E/flutter (23028): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: type 'Null' is not a subtype of type 'Map<String, dynamic>' in type cast
E/flutter (23028): #0      _LoginScreenState.build.<anonymous closure>.discoverUser.<anonymous closure> (package:choice_hi/screens/login.dart:45:45)
E/flutter (23028): #1      _LoginScreenState.build.<anonymous closure>.discoverUser.<anonymous closure> (package:choice_hi/screens/login.dart:44:23)

I am unsure of what is wrong with my code. Could you advise me of how to fix it so that data from the collection can be retrieved please?

At this stage I am also uncertain about the Firestore security rules that I need in order for the data request to be approved by Firestore. Could you also offer some general advice on the type of permission I need to allow please?

When I began writing the method, I was using the 'get' function and then I changed to 'doc.data()'. Is it at all possible to rely on 'get' to retrieve one item of data from a collection please?

Many thanks for your time and your assistance.


Solution

  • The error you get is:

    type 'Null' is not a subtype of type 'Map<String, dynamic>' in type cast

    That comes from one of the two lines in your code that looks like this:

    final data = doc.data() as Map<String, dynamic>
    

    It seems that the document doesn't have any data (so it doesn't exist), and your code doesn't handle that.

    The way to check whether the document you got exists is with doc.exists before calling data() on it.

    So:

    await pDocRef.get().then((DocumentSnapshot doc) {
      if (doc.exists) {
        final data = doc.data() as Map<String, dynamic>;
        userAge = data['userAge'];
      }
      else {
        print('Document does not exist');
      }
    },
    onError: (e) => print('Error getting document $e'),
    );