Ocrimops
Ocrimops

Reputation: 163

Hot to safely get data from cloud-firestore in flutter even if the requested field is missing in the document?

I have several documents in my users collection which do not have all possible fields yet.

Getting my users from Firestore (using cloud_firestore: ^2.2.1) it throws an error.

Bad state: field does not exist within the DocumentSnapshotPlatform

I provoked this error inside the try-catch block.

...
  factory User.fromFirestore(DocumentSnapshot doc) {

    try {
      print(doc.get('some-missing-field'));
    } catch (e) {
      print(e);
    }

    return User(
      id: doc.id,
      email: doc.get('email') ?? '',
      displayName: doc.get('displayName') ?? '',
      fieldfoo: doc.get('fieldfoo') ?? '',
      fieldbar: doc.get('fieldbar') ?? [],
    );
  }
}
...

At which point did I miss to tell flutter, that it should fill up missing fields with dummy values?

Are there any best practices? Did anyone face into a similar issue?

Upvotes: 0

Views: 917

Answers (2)

Ocrimops
Ocrimops

Reputation: 163

The solution was to Map the DocumentSnapshot to <String, dynamic> at every occurence.

The resulting function looks like

...
  factory User.fromFirestore(DocumentSnapshot<Map<String, dynamic>> doc) {
    Map data = doc.data()!;
    return User(
      id: doc.id,
      email: data['email'] ?? '',
      displayName: data['displayName'] ?? '',
      language: data['language'] ?? '',
      affiliatedOrganizations: data['affiliatedOrganizations'] ?? [],
      isAdmin: data['isAdmin'] ?? false,
      isEditor: data['isEditor'] ?? false,
    );
  }
...

This "query" results all users.

  final Stream<QuerySnapshot<Map<String, dynamic>>> _usersStream =
      DatabaseService().usersCollection.snapshots();
  

When I sort with a field, which some user-documents do not have, those user-documents won't be shown

  final Stream<QuerySnapshot<Map<String, dynamic>>> _usersStream =
  DatabaseService().usersCollection.orderBy('displayName').snapshots();

Not all users have a "displayName", so they are not listed in my result.

Anyone knows how to bypass that?

Upvotes: 0

Tarik Huber
Tarik Huber

Reputation: 7398

If you are using null safety you can get it like this:

Map<String, dynamic>? data = docSnapshot.data();
var value = data?['field_name'] ?? '';

Upvotes: 1

Related Questions