type 'Null' is not a subtype of type 'Map<String, dynamic>' - Flutter

1,718

You're telling the compiler that map might be null by putting the ? on the type, but after that you're stating that map will never be null by putting the ! on map in the custId line. Probably removing the ! will suffice.

Share:
1,718
Faizan Kamal
Author by

Faizan Kamal

Updated on December 19, 2022

Comments

  • Faizan Kamal
    Faizan Kamal over 1 year

    I'm getting the following error while fetching data from firestore but I know this error is not about how I'm fetching data. It is related to the null safety which was added in latest flutter update. I'm not so much familier with it.

    ════════ Exception caught by provider ══════════════════════════════════════════
    The following assertion was thrown:
    An exception was throw by _MapStream<DocumentSnapshot, CustData> listened by
    
    StreamProvider<CustData>, but no `catchError` was provided.
    
    Exception:
    type 'Null' is not a subtype of type 'Map<String, dynamic>'
    
    ════════════════════════════════════════════════════════════════════════════════
    
    class MainDataProvider extends StatefulWidget {
      const MainDataProvider({Key? key}) : super(key: key);
    
      @override
      _MainDataProviderState createState() => _MainDataProviderState();
    }
    
    class _MainDataProviderState extends State<MainDataProvider> {
     @override
      Widget build(BuildContext context) {
        User? user = FirebaseAuth.instance.currentUser; 
    
        StreamProvider custDataProvider = StreamProvider<CustData>.value(
          initialData: CustData.initial(),
          value: DatabaseService(uid: user?.uid).getCustData, 
           // ^^^^^^^^ I'm getting error while getting custdata
        );
    
        return MultiProvider(
          providers: [custDataProvider],
          child: const Scaffold(
            body: HomeView(),
          ),
        );
      }
    }
    
      Stream<CustData> get getCustData =>
          custCollection.doc(uid).snapshots().map(_custDataFromSnapshot);
    
      CustData _custDataFromSnapshot(DocumentSnapshot snapshot) => CustData.fromMap(snapshot.data());
    

    To avoid this error "The argument type 'Map<String, dynamic>?' can't be assigned to the parameter type 'Map<String, dynamic>'" I added "?" after below parameter but after putting "?" I'm getting the above error. I know I'm missing a small piece of puzzle

    class CustData {
      String custID;
      String name;
      String phoneNo;
      String email;
      Map<String, dynamic> favs;
      ReferDetails referDetails;
    
      CustData({ ... });
    
    // To avoid this error "The argument type 'Map<String, dynamic>?' can't be assigned to the parameter type 'Map<String, dynamic>'" I added "?" after below parameter but after putting "?" I'm getting above error
    //  B E L O W    H E R E 
      factory CustData.fromMap(Map<String, dynamic>? map) {
        return CustData(
          custID: map!['custID'] ?? '',
          name: map['name'] ?? '',
          phoneNo: map['phoneNo'] ?? '',
          email: map['email'] ?? '',
          favs: map['favs'] ?? {},
          referDetails: ReferDetails.fromMap(map['referDetails']),
        );
      }
    }
    

    Here is database view

    enter image description here

    • Ahmad F
      Ahmad F about 2 years
      What would happen if favs is declared as Map<String, dynamic>? favs? Also, are you sure that there are favs in the response?
    • Faizan Kamal
      Faizan Kamal about 2 years
      I updated the question. Added a picture of the database. favs existed
  • Faizan Kamal
    Faizan Kamal about 2 years
    After removing "!", I get this. gcdnb.pbrd.co/images/LziF2dwQq9LI.jpg?o=1
  • Faizan Kamal
    Faizan Kamal about 2 years
    Is there any other way to tackle it?
  • il_boga
    il_boga about 2 years
    You must handle the case when map is null. You can put something like if (map == null) throw ArgumentError(); before the return, but you must be prepared to handle in some way the error. Otherwise, you can remove the ? from the type declaration, but this just moves the problem upwards.
  • il_boga
    il_boga about 2 years
    Wait, my bad. You should be able to change your code like this: custID: map?['custID'] ?? '', so that if map is null, custId would be set at the value specified after the ??. This must be done on each line, of course.