I got a error on code data.docs . I want to display all data from firestore - firebase

I have an error on data.docs . It always show an error on the docs code. i want to display all the data from firestore

Looking at it, it seems you have not set a return type for your FutureBuilder or StreamBuilder. If you wish to access properties on snapshot.data, you should type the future or stream. For example doing
FutureBuilder<QuerySnapshot>
allows you to access methods on the QuerySnapshot class like
snapshot.data!.docs

Related

Flutter gives null error, but works after restart

I am new to Flutter, I am trying to fetch data from firestore collection. I am using FutureBuilder with Provider, but it shows null error on initial & runs perfectly after restarting the app.
Here is the code to fetch the data:
FutureBuilder<QuerySnapshot>(
future: FirebaseFirestore.instance
.collection(collec.collectionProducts)
.get(),
builder: (context, snapshot) {
return Consumer<CartItemCounter>(
builder: (BuildContext context, CartItemCounter cart, _) {
if (cart.checkProductAddedToCart(model.productId)) {
return Row(....);
Error
code for futurebuilder
code for ui
(here i have changed the collection name)
How can i solve it. I have tried every solution available on online. Thank you
Where is the error coming from?
According to this, the issue is coming from your Consumer<CartItemCounter>.
What does the error mean?
This error, The method 'x' was called on null., means that the class where this x function is written, that class is null.
What is the reason for this error in my code?
Your Consumer<CartItemCounter> provides an instance of CartItemCounter by the name cart. Then, you call function checkProductAddedToCart.
The error message is telling you that cart is null which is being given to you by the Consumer widget. This means that Consumer probably also did not find that Provider. I expect that there should be an error log by Provider, telling you that CartItemCounter was not found.
Possible Solution
Try 'providing' CartItemCounter.
How do you do that? Go to the top of your app's widget tree to MaterialApp, wrap it inside a MultiProvider or ChangeNotifierProvider and then pass your new CartItemCounter as value.
Read Official Provider Docs for more info on how to expose a provider.
You need to upload your complete log, so that I can further help you.
Always check the result for the future builder, ie snapshot has data.
Place a switch condition or if-else bock depending on the status of the snapshot.
check the example from the official doc here

Flutter & Firebase: How to populate an array and then later, return all the contents

I have been trying to get arrays working in Firebase, and I am aware that there are a lot of references and discussions about this online, and I have read through all of these and none of it works.
First off, the Firebase side. The structure containing the array and two example strings inside it:
Firebase Structure
collection -> document -> fields
userData profileImages URLs (array)
: https://firebasestorage.googleapis.com/v0/b/app-138804.appspot.com/o/jRwscYWLs1DySLMz7jn5Yo2%2Fprofile%2Fimage_picker4459623138678.jpg?alt=media&token=ec1043b-0120-be3c-8e142417
: https://firebasestorage.googleapis.com/v0/b/app-138804.appspot.com/o/jRwscYWLs3872yhdjn5Yo2%2Fprofile%2Fimage_picker445929873mfd38678.jpg?alt=media&token=ec3213b-0120-be9c-8e112632
The first issue I am facing is writing to this array in the database:
Firestore.instance.collection('userData').document('profileImages').updateData({
'URLs': _uploadedFileURL,
});
Whenever I add data to this array, it just overwrites the existing data. I need to be able to keep all the existing data intact and simply add the current new line to the array.
Once this is working, I then need to be able to return all of the strings in this array without needing to know how many of them there will be.
For this part, I basically have nothing at this point. I could show some of the things I have tried based on suggestions from other articles on this, but none of it is even close to working correctly.
im assuming that _uploadedFileURL is a String, and you are updating the property URLs, that's why your data gets overwritten, because you are changing the URLs value to a single string which is _uploadedFileURL. to solve this issue, simply get the current data inside profileImages before commiting the update. like so
final DocumentSnapshot currentData = await Firestore.instance.collection('userData').document('profileImages').get();
Firestore.instance.collection('userData').document('profileImages').updateData({
'URLs': [
...currentData.data['URLs'],
_uploadedFileURL
],
});
and for the second part of your question, all you need is to query for the profileImages
Future<List<String>> _getProfileImages() {
final document = Firestore.instance.collection('userData').document('profileImages').get();
return document.data['profileImages]
}
the result of the get method will be a DocumentSnapshot, and inside the data property will access the profileImages which is a List<String>.
Ok guys and girls I have worked this out. Part 1: appending data to an array in Firebase.
Firestore.instance.collection('userData').document('profileImages').updateDataupdateData({
'URLs':FieldValue.arrayUnion([_uploadedFileURL]),
});
Where _uploadedFileURL is basically a string, for these purposes. Now I have read that arrayUnion, which is super groovy, is only available in Cloud Firestore, and not the Realtime Database. I use Cloud Firestore so it works for me but if you are having issues this might be why.
Now what is extra groovy about Cloud Firestore is that you can similarly remove an element from the array using:
Firestore.instance.collection('userData').document('profileImages').updateDataupdateData({
'URLs':FieldValue.arrayRemove([_uploadedFileURL]),
});
So how to get this data back out again. A simple way I have found to get that data and chuck it into a local array is like so:
List imageURLlist = [];
DocumentReference document = Firestore.instance.collection('userData').document('profileImages');
DocumentSnapshot snapshot = await document.get();
setState(() {
imageURLlist = snapshot.data['URLs'];
});
From here at least you have the data, can add to it, can remove from it and this can be a platform for you to figure out what you want to do with it.

Flutter firestore fetch documents with a condition on a map field

So I have a document in this form:
Field:
NestedField: Value
How can I use the where() method in Flutter to fetch all documents that satisfy a condition on NestedField? I.e:
Firestore.collection("forms").where("Field.NestedField",isEqualsTo: "Op1").getDocuments(). // This returns null
Alright, so this was caused by another error with no relation to Firestore directly. The Field.NesterForm approach works and it returns the data. Since Firestore uses JSON then it's the correct way to access nested fields this way. The code I was testing with was:
List<DocumentSnapshot> docs;
await Firestore.instance.collection('form')
..where("FirstForm.Operator",isEqualTo: _filter.text)
.getDocuments().then((query) {
docs = query.documents;
});
print("DOCS: $docs");
The .. before the where() that I didn't see at first caused the awaitto not actually wait for the return so the print of my docs variable always returned null. Once I removed one dot, it works fine now and the equals is working.

Uploading Set<String> gives error in flutter

Okay, so I'm creating chips tiles that are stored in a Set, but when I try to upload it to firebase I get this error "Unhandled Exception: Invalid argument: Instance of '_CompactLinkedHashSet'"
I isolated the code and simplified it so it looks like this:
...
Set<String> _tags = <String>{};
_tags.add('Test1');
Firestore.instance
.collection('tags')
.document(tagsID)
.setData({
'tags': _tags,
});
...
I've tried debugging it, and I can't get it to upload so is there any other kind of way I can get the data from the set and upload it to Firebase? Another data type I can use that Firebase will accept?
Take a look at the data types that Firestore supports. Sets are not supported. You could convert your set to a JSON string, or to a list:
List<String> tagsList = List<String>.from(_tags);
Adding on to Bryson Thill's answer, if you need to use Sets in your code, I'd recommend you use the toList() method before uploading to Firestore.
I would suggest you following the answer from this question:
Adding an Object to Cloud Firestore using Flutter
And you can basically upload any data you want

How to create custom index for firestore query

I need to be able to retrieve some data from my cloud firestore database where certain conditions are met and then order that data but I am unable to get my query to work. I've read that if you simply run the query then your log should provide you a link to automatically create the custom index but unfortunately within my flutter logs or the android studio logcat i'm not getting any links. I know you can create the custom indexes manually in the firebase console so i'm happy to do this but I dont know how I would create the index for this.
firestore.collection('users').where('organisation_id', isEqualTo: _authenticatedUser.organisationId)
.orderBy('first_name').getDocuments()
I just need to know how to create the composite index for this query so that it will work in my app
I was able to get a link in my console log by surrounding the firestore query with a try catch and printing out the platform exception which generated the direct link, thanks to Dougs answer
try {
snapshot = await firestore.collection('users').where(
'organisation_id', isEqualTo: _authenticatedUser.organisationId)
.orderBy('first_name').getDocuments();
} catch(e){
print(e);
}

Resources