'Flutter: Unhandled Exception: Bad state: field does not exist within the DocumentSnapshotPlatform
I am new to flutter and i am building a social media App through tutorial which i am now customizing.
Now I tried to add more input fields to a users profile page then i started getting the error below. When i could login my timeline page turned red with warning Bad state: field does not exist within the DocumentSnapshotPlatform
I ran Flutter clean and now my user cannot log into the app
I am getting this error:
E/flutter ( 3971): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Bad state: field does not exist within the DocumentSnapshotPlatform
E/flutter ( 3971): #0 DocumentSnapshotPlatform.get._findKeyValueInMap
package:cloud_firestore_platform_interface/…/platform_interface/platform_interface_document_snapshot.dart:82
E/flutter ( 3971): #1 DocumentSnapshotPlatform.get._findComponent
package:cloud_firestore_platform_interface/…/platform_interface/platform_interface_document_snapshot.dart:98
E/flutter ( 3971): #2 DocumentSnapshotPlatform.get
package:cloud_firestore_platform_interface/…/platform_interface/platform_interface_document_snapshot.dart:113
E/flutter ( 3971): #3 DocumentSnapshot.get
package:cloud_firestore/src/document_snapshot.dart:49
E/flutter ( 3971): #4 DocumentSnapshot.[]
package:cloud_firestore/src/document_snapshot.dart:56
E/flutter ( 3971): #5 new User.fromDocument
package:findemed/models/user.dart:46
E/flutter ( 3971): #6 _HomeState.createUserInFirestore
package:findemed/pages/home.dart:152
E/flutter ( 3971): <asynchronous suspension>
E/flutter ( 3971): #7 _HomeState.handleSignIn
package:findemed/pages/home.dart:60
E/flutter ( 3971): #8 _HomeState.initState.<anonymous closure>
package:findemed/pages/home.dart:46
E/flutter ( 3971): #9 _rootRunUnary (dart:async/zone.dart:1198:47)
The initial was pointing to this dart section of my home file
buildUsersToFollow() {
return StreamBuilder(
stream: usersRef.orderBy('timestamp', descending: true)
.limit(0)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return circularProgress(context);
}
List<UserResult> userResults = [];
snapshot.data.docs.forEach((doc) {
User user = User.fromDocument(doc);
final bool isAuthUser = currentUser.id == user.id;
final bool isFollowingUser = followingList.contains(user.id);
// remove auth user from recommended list
if (isAuthUser) {
return;
} else if (isFollowingUser) {
return;
} else {
UserResult userResult = UserResult(user);
userResults.add(userResult);
}
});
Now its pointing to this snippet:
factory User.fromDocument(DocumentSnapshot doc) {
return User(
id: doc['id'],
email: doc['email'],
username: doc['username'],
photoUrl: doc['photoUrl'],
displayName: doc['displayName'],
bio: doc['bio'],
fullNames: doc['fullNames'],
practice: doc['practice'],
speciality: doc['speciality'],
phone: doc['phone'],
mobile: doc['mobile'],
emergency: doc['emergency'],
address: doc['address'],
city: doc['city'],
location: doc['location'],
);
}
and this is the other bit of code pointed out in the stack
currentUser = User.fromDocument(doc);
print(currentUser);
print(currentUser.username);
Solution 1:[1]
For the latest version of cloud_firestore (2.4.0 or above) finally i found the solution:
And the older version of cloud_firestore it is solved by simply adding ?? at the end to avoid a null value:
factory User.fromDocument(DocumentSnapshot doc) {
return User(
id: doc.data()['id'] ?? '',
);
}
but in the new version that not possible because return Bad state
factory User.fromDocument(DocumentSnapshot doc) {
return User(
id: doc.get('id')
);
}
And it is solved by simply checking that the doc contains the key:
factory User.fromDocument(DocumentSnapshot doc) {
return User(
id: doc.data().toString().contains('id') ? doc.get('id') : '', //String
amount: doc.data().toString().contains('amount') ? doc.get('amount') : 0,//Number
enable: doc.data().toString().contains('enable') ? doc.get('enable') : false,//Boolean
tags: doc.data().toString().contains('tags') ? doc.get('tags').entries.map((e) => TagModel(name: e.key, value: e.value)).toList() : [],//List<dynamic>
);
}
Hope this helps, regards! :)
Solution 2:[2]
I had the same problem and I solved it by asking if the parameter exists.
This was my previous code:
if(widget.document['imageUrl'] == null)//here was my error, I was calling a field that did not exist in the document
Container(
child:Icon(
Icons.image,
size: 20.0,
color: Colors.grey,
),
),
This is how it works for me:
if(widget.document.data().containsKey('imageUrl'))
Container(
child:Icon(
Icons.image,
size: 20.0,
color: Colors.grey,
),
),
Solution 3:[3]
This issue can also happen by passing wrong attribute name that does not exist in the document , while displaying document data in a builder method. This solved the issue for me.
Solution 4:[4]
Simple solution would be using data() from the DocumentSnapshot and cast it as Map<String,dynamic>, and finally you can check if key exists on Map or not as shown in given code snippets.
fireStore.collection('transactions').get().then((QuerySnapshot querySnapshot) {
List<TransactionModel> transactions = [];
querySnapshot.docs.forEach((DocumentSnapshot doc) {
transactions.add(TransactionModel.fromJson(doc.data() as Map<String,dynamic>));
});
onResponse(FireStoreApiResponse.withSuccess(transactions));
}).catchError((onError) {
onResponse(FireStoreApiResponse.withError(onError));
});
In TransactionModel class
TransactionModel.fromJson(Map<String, dynamic> json) {
date = json['date'];
memberId = json['member_id'];
if (json.containsKey("member_contact")) memberContact = json['member_contact'];
if (json.containsKey("member_name")) memberName = json['member_name'];
packageId = json['package_id'];
grossAmount = json['gross_amount'];
discount = json['discount'];
netAmount = json['net_amount']; }
Solution 5:[5]
Error (Bad State : Field Does not exists within the document) only Occurs when you Type Case Sensitive Field name in your Flutter Code or field name which does exists in yours firestore collections fields.
Remember field Names are Case Sensitive so you have to use same field as mentioned in your firestore collection field
For Example:- Your Firebase Firestore Collection Field Contains 'Username' field and you have used 'username' in your Flutter code then this error occurs. So to fix this error use same field name as mentioned in Firestore
This is Cloud FireStore Collection Fields Contain "UserName", etc so you have to use Exactly same in your Flutter Code Check Cloud FireStore Collection Fields
due to case Sensitivity This is correct because collections field exist as ("UserName") in Firestore Collections and used ("UserName") in Flutter Code
Correct FieldName forFlutter Code due to case Sensitivity This is Wrong because collections field exist as ("UserName") in Firestore Collections and used ("username") in Flutter Code Wrong FieldName forFlutter Code
If you need more help just ping me... Happy Coding
Solution 6:[6]
A better and simple way
factory User.fromDocument(DocumentSnapshot snap) {
var doc = snap.data();
id: doc['id'],
email: doc['email'],
......
......
}
Solution 7:[7]
I has the same issue. Later found that it was due to a trailing space in the key name in Firestore.
Solution 8:[8]
Make sure to convert the documentSnapshot.data() to a Map<String, dynamic> first.
The thing is that when you are searching for the key-value if the key is not available then it throws an error of bad state. To handle this you can use optional types available with the null safety feature. A sample code is given below:
final _data = documentSnapshot.data() as Map<String, dynamic>;
final CourseModel _courseModel = CourseModel(
name: _data['name'] ?? "",
imageLink: _data['imageLink'] ?? "",
details: _data['details'] ?? "",
trending: _data['trending'] ?? false,
id: _data['id'] ?? "",
discount: _data['discount'] ?? 0,
);
On top you can see that there is a ?? to handle if there is no value available for a key. For example if the discount is not available then by default it sets the value to 0.
Solution 9:[9]
This error occurs when any parameter key is missing or has a typo in it as compared to firebase declared fields.
For Example: inside the firebase document, we have a key/value username.
username: "Ali Murtaza"
Now if inside the model if we miss it or write it like this:
username: doc["usernameeeeee"] as String
then bad state: field does not exception will occur.
To handle this case, we have to check whether the document we are fetching contains the particular field or not? To check this:
username: doc.data()!.containsKey("username")
? doc["username"] as String
: "Username Key Does Not Exist inside Firebase Document",
Note: If this answer helped you, then hit the vote button-up, so the answer can reach others in the future.
Solution 10:[10]
Implement extension method for the DocumentSnapshot type.
In 2022 the simplest solution for me is to implement an extension method of the DocumentSnapshot type. This can be setup to overwrite the get method entirely (no example shown here), or implement custom methods for more strongly-typed data (example shown below).
The core functionality of the methods should follow the pattern noted in this answer. If you create this extension in a separate file and import it you'll also need to import the cloud_firestore dependency into that file in order to access the DocumentSnapshot type.
In this example the new methods become available directly on the snapshot.
extension CustomGetters on DocumentSnapshot {
int getInt(key) {
return this.data().toString().contains(key) ? this.get(key) : 0;
}
String getString(key) {
return this.data().toString().contains(key) ? this.get(key) : '';
}
}
To access, just call your custom methods rather than the usual get method:
/**...fetch the snap...then...**/
snap.getInt('id');
snap.getString('username');
Solution 11:[11]
I think this is because of the .limit(0) clause.
Solution 12:[12]
this also happens when the document which you are calling is null.
Solution 13:[13]
I solved this error by changing my query to update the values in the database rather than set them because apparently one field was being deleted and hence could not retrieve its value. This can help people who face the same error and have the same set up as mine.
Solution 14:[14]
Instead of Using this:
factory User.fromDocument(DocumentSnapshot doc) {
return User(
id: doc['id'],
email: doc['email'],
username: doc['username'],
photoUrl: doc['photoUrl'],
displayName: doc['displayName'],
bio: doc['bio'],
fullNames: doc['fullNames'],
practice: doc['practice'],
speciality: doc['speciality'],
phone: doc['phone'],
mobile: doc['mobile'],
emergency: doc['emergency'],
address: doc['address'],
city: doc['city'],
location: doc['location'],
);
}
I used ::
factory User.fromDocument(DocumentSnapshot doc) {
return User(
id: doc.get('id'),
email: doc.get('email'),
username: doc.get('username'),
photoUrl: doc.get('photoUrl')
displayName: doc.get('displayName'),
bio: doc.get('bio'),
fullNames: doc.get('fullNames'),
practice: doc.get('practice'),
speciality: doc.get('speciality'),
phone: doc.get('phone'),
mobile: doc.get('mobile'),
emergency: doc.get('emergency'),
address: doc.get('address'),
city: doc.get('city'),
location: doc.get('location'),
);
}
It Solved the problem for me...
Solution 15:[15]
To check Firebase and Local value same key of all data ie, doc['id']
here 'id' is key check same as in your firestore.
id: doc['id'],
email: doc['email'],
username: doc['username'],
photoUrl: doc['photoUrl'],
displayName: doc['displayName'],
bio: doc['bio'],
fullNames: doc['fullNames'],
practice: doc['practice'],
speciality: doc['speciality'],
phone: doc['phone'],
mobile: doc['mobile'],
emergency: doc['emergency'],
address: doc['address'],
city: doc['city'],
location: doc['location'],
check and rerun
Solution 16:[16]
Unless you're careless, this error is not code related. There may be differences between the fields in the database and the data in its class.
Example: Class Student{String? name,String? department,String? school}
Database: 1-> name=xxx, no=xxx 2-> name=yyy, no=yyy ,school=yyy
All fields must match correctly.
Solution 17:[17]
**
Be sure the name of the document on your builder is the same name on your firestore database document name.
**
Solution 18:[18]
Use this :
Map<String, dynamic> data = doc.data() as Map<String, dynamic>;
data['SOMEKEY'].toString();
int.parse(data['SOMEKEY'].toString());
for boolean use if(data['SOMEKEY'] == true)
Solution 19:[19]
let say final Map<String, dynamic> doc so you can check for any field available in doc variable doc.keys.contains('anyField') it will true if field available otherwise false.
Solution 20:[20]
This error is because, The field you are calling from the document does not exists. Even a single field can cause this error.
Solution 21:[21]
Accepted answer did not work for me, the below code worked for me. If field is not available from Firebase, the code below will still work
factory User.fromDocument(DocumentSnapshot doc) {
Map<String, dynamic> json = doc.data() as Map<String, dynamic>;
return User(
id: json['id'],
email: json['email'],
username: json['username'],
photoUrl: json['photoUrl'],
displayName: json['displayName'],
bio: json['bio'],
fullNames: json['fullNames'],
practice: json['practice'],
speciality: json['speciality'],
phone: json['phone'],
mobile: json['mobile'],
emergency: json['emergency'],
address: json['address'],
city: json['city'],
location: json['location'],
);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
