im new to flutter and dont know exactly what to search for this one but, can we use the auto generated ID like in the picture to retrieve all that data UNDER that ID? if so, how ? In a similar question that I stumbled upon, they use database.reference() but its a Realtime Database and not FireStore
Im using Firebase Cloud Firestore
There is no AutoId in firebase but here is a quick way to set as auto id
Forexample ;
1- create yourModel ( which one u gonna send as model to firebase )
2- DatabaseReference firebaseDatabase;
3- firebaseDatabase =FirebaseDatabase.instance.reference();
4- firebaseDatabase.child("table_name").push().set( yourModel.toJson() );
Also for getting data u can write code like that
var result= firebaseDatabase.child("table_name").once().then(
(DataSnapshot datasnapshot){
Map<dynamic,dynamic> values= datasnapshot.value;
values.forEach((key,value){
print("key:"+key+" value:"+value["name"]);
});
}
);
print(result);
I tried it and works great
Have a nice day !!!
I'm guessing you're asking about subcollections.
If you read a document (by its (auto-generated or not) key), you get back that document. You don't get back data from any subcollection. That will require a separate read operation for each subcollection under the document that you want to read.
Related
Im trying to create one stream, that is using multiple documents references that are stored and fetched from Firebase Firestore.
Lets say I have two collection named users and documents. When user is created he gets document with his id in users collection with field named documentsHasAccessTo that is list of references to documents inside documents collection. It is important, that these documents can be located in different sub collections inside documents collection so I dont want to query whole documents and filter it, in order to save Firestore transfer and make it faster I already know paths to documents stored in documentsHasAccessTo field.
So for example, I can have user with data inside users/<user uid> document with documentsHasAccessTo field that stores 3 different document references.
I would like to achieve something like this (untested):
final userId = 'blablakfn1n21n4109';
final usersDocumentRef = FirebaseFirestore.instance.doc('users/$userId');
usersDocumentRef.snapshots().listen((snapshot) {
final references = snapshot.data()['documentsHasAccessTo'] as List<DocumentReference>;
final documentsStream = // create single query stream using all references from list
});
Keep in mind, that it would also be great, if this stream would update query if documentsHasAccessTo changes like in the example above, hence I used snapshots() on usersDocumentReferences rather than single get() fetch.
The more I think about this Im starting to believe this is simple impossible or theres a more simple and clean solution. Im open to anything.
You could use rxdart's switchMap and MergeStream:
usersDocumentRef.snapshots().switchMap((snapshot) {
final references = snapshot.data()['documentsHasAccessTo'] as List<DocumentReference>;
return MergeStream(references.map(ref) => /* do something that creates a stream */));
});
Why I cant use whereQuery in collectionGroup.
When I use whereQuery like that;
Query colRef = _firestore.collection("users");
colRef = colRef.where("name", isEqualTo: widget.name);
Its working, but when I use whereQuery like that;
Query colRef = _firestore.collectionGroup("users");
colRef = colRef.where("name", isEqualTo: widget.name);
Its not working, while geting the data, I query whether there is an error by using hasError and if else, and I get an error. and I must use collectionGroup while getting data from firebase.
Is there a solution to use whereQuery in collectionGroup?
Firestore Index Settings
I guess I need to somehow enable the disabled options here, but I don't know how to do it.
In summary I want all users in the application to have access to all kinds of data that I specify in the collection Group.
I need to set the composite and exemption part at the same time, when I set both parts according to the paths I want to query, the problem was solved.
I have my dataset modeled within the Firebase Firestore database as shown below:
I would like to retrieve and display the data based on the following criterias:
isAdmin is equal to true
isPerm is equal to true
userID sorted in descending order
I'm using the following versions of Firebase and Cloud Firestore packages:
firebase_core: ^0.5.0
cloud_firestore: ^0.14.0+2
I'm new to Flutter, I'm not sure, how I can achieve this. Really appreciate, if anyone could help me with this. Thanks for your help in advance.
I was able to retrieve the data as shown below, not sure how to sort it in descending order.
getUsers() async {
// _userCollection.doc('uGGuMfGS2DezVHHFASw4').where('userData', arrayContainsAny('isAdmin', isEqualTo: true)).get();
final _docRef = await _userCollection.doc('uGGuMfGS2DezVHHFASw4').get();
print(_docRef.data()['userData'].length);
for (var i = 0; i < _docRef.data()['userData'].length; i++) {
print(_docRef.data()['userData'][i]['username']);
print(_docRef.data()['userData'][i]['isAdmin']);
}
}
What you are trying to do with this data is not possible. Firestore does not have a way to query for specific map values nested in array fields. You will have to restructure this data to make it workable with Firestore.
One thing you can do is move all those array items into separate documents in a subcollection, then query the subcollection.
Another thing you can do is copy each nested value into an array to query with an array-contains type query.
I am trying to structure my data such that when someone adds a new product to the database, all users receive the new product in their list and therefore the new product appears on their screen.
But if a user decides to delete that product, they can delete it but only for themselves. Is there a Cloud Firestore sorting/ordering/filtering that I should be using to accomplish this?
I thought I could use something like the following:
final theProduct = Provider.of<Products>(context);
products = await firestore.collection('products').getDocuments()
for (product in products.documents) {
await firestore.collection('products').add({
'nameOfProduct': theProduct.nameOfProduct
});
}
But I get a document property error.
Maybe I need to go in one more collection and then try something? But I also need to be able to retrieve the data back using the userID of the signed in user..
Any hints/helpful links would be greatly appreciated.
So I think what I want to do is iterate through all documents within a collection and then document().collection('').add() something to each of their collection. Hopefully that sheds some more light on my problem.
Thanks to those who commented. I found a way to implement this was to use the unique value that each product contains and add it to a list on a per user basis in Firestore. Then fetch that list from Firestore and filter out the corresponding products. No deleting necessary.
Question : a user decides to delete that product, they can delete it but only for themselves
Answer: U can create list in user profile section where u can have all the product document ids & u can use that document id to fetch particular product details & when user click on delete button u can remove that particular document id from there collection
Im not sure what r u doing with sample code over there.
If u want to add data to database then use :
await Firestore().collection('Products').add({
'nameOfProduct': theProduct.nameOfProduct,
});
this will generate document random id for your product.
To get data from particular id use :
DocumentSnapshot documentSnapshot = await Firestore().collection('Products').document('document').get();
then u can use that document snapshot to get data for particular key e.g.
documentSnapshot.data['Product Name']
In Firestore I am trying to update avatar (photoUrl) on multiple locations when the user changes the avatar.
Data structure: https://i.imgur.com/yOAgXwV.png
Cloud function:
exports.updateAvatars = functions.firestore.document('users/{userID}').onUpdate((change, context) => {
const userID = context.params.userID;
const imageURL = change.after.data().avatar;
console.log(userID);
console.log(imageURL);
});
With this cloud function, I am watching on user update changes. When the user changes avatar I got userID and a photo URL. Now I want to update all "todos" where participant UID is equal to userID.
You could use the array_contains operator for your query. This allows you to search for array values inside your documents.
https://firebase.google.com/docs/firestore/query-data/queries#array_membership
If you found your documents you have to update the URL on all documents and write the updated documents back to the database.
But this causes a lot of unnecessary writes especially if your todos collection gets bigger and you want to archive the todos data.
Simpler solution:
I suspect a to do list does not have more then 10 users if so this is a lot of trouble to save some document reads.
I would recommend you to just load all user documents you need to show the avatar on the to do list.