Can't get one document from flutter cloud firestore - flutter

I'm trying to get one document by user id from firebase cloud firestore using flutter.
I tried firstly to fetch the data then added a condition to it, but i'm not able to display the data or even print it in the console!
Here is what i've tried so far:
database.dart:
Future<DocumentSnapshot?> getFileByUser(String userId) async {
return FirebaseFirestore.instance
.collection('cartesPro')
.where('cartUserId', isEqualTo: FirebaseAuth.instance.currentUser!.uid)
.get()
.then((value) {
value.docs.forEach((element) {
print(element.id);
});
});
}
ui page:
User? user = FirebaseAuth.instance.currentUser;
showFile() {
final files = DatabaseMethods().getFileByUser(user!.uid);
print(files);
}
and then made the call in a button so I can print the result only! it's returning the documents of the actual user, but I couldn't map the result in order to get the latest in timestamp order!
I appreciate any kind of help, thanks in advance!

If you want to get the most recent document for the user, you should order on the field that has the timestamp and the limit to a single result:
FirebaseFirestore.instance
.collection('cartesPro')
.where('cartUserId', isEqualTo: FirebaseAuth.instance.currentUser!.uid)
.orderBy('timestamp', descending: true)
.limit(1)
.get()
See the Firestore documentation on ordering and limiting data for more on this.

Related

Firestore database query issue

I want to fetch all the data from password_entries if the user_id is "BED3wChei4NEiDfQP72atUz2NU43"
How can I perform the same.
You can use the following method:
FirebaseFirestore.instance
.collection('password_entries')
.where('user_id ', isEqualTo: "BED3wChei4NEiDfQP72atUz2NU43")
.get()
.then((checkSnapshot) {
// Document found - do something with it
print(checkSnapshot.docs[0].data());
});

FirebaseException: Not able to query a collectionGroup

I am trying to do a pretty simple query in firebase for a collectionGroup. I only want to get all the products that are of the type "Restuarant". The code is below:
QuerySnapshot res = await FirebaseFirestore.instance
.collectionGroup('products')
.where("type", isEqualTo: "Restuarant")
.get();
It keeps throwing a FirebaseException as below:
I have added an exception in the Firebase indexes. It is a single field index.
What is the issue here? Why is this Exception occurring?
So I was able to get it working by adding a composite index. After adding the composite index, I was able to perform orderBy query too, using the rating field.
QuerySnapshot res = await FirebaseFirestore.instance
.collectionGroup('products')
.where("type", isEqualTo: "Restuarant")
.orderBy("rating", descending: true)
.get();

how to delete document by field inside collection inside document inside collection on firestore

I have Doctor collection when each doctor (represent by his email ) has a collection called patients_waiting.
Now, what I'm trying to do is delete one document from the paitents_waiting collection by field calls patients containing his email.
but I tried many solutions and none of them works for me now.
what I have tried to do :
Firestore.instance
.collection("Doctors")
.document(doctorEmail)
.collection("paitents_waiting")
.document(paitentEmail)
.delete();
now it's not good because the document is saved in uid and not by email but I tried to play with the where function but with no success.
how do I found this document by email and delete him?
I will mention that I'm doing it on flutter, but I think it doesn't matter.
as long as you have the patient's email address you can search with and delete it
Firestore.instance
.collection("Doctors")
. document(doctorEmail)
.collection("paitents_waiting")
.where('patient', isEqualTo:paitentEmail )
.get().then((value) => value.docs.single.reference.delete())
Nb: you are using an old version of firestore
Inside your paitents_waiting collection, the documents are NOT named according to patient email, they are randomly generated Firebase IDs. Take a closer look.
Firestore.instance
.collection("Doctors")
.document(doctorEmail)
.collection("paitents_waiting")
.document(paitentEmail) //this in your Firebase isn't an email, it's "xaErf43Asd..etc"
.delete();
If you want to follow this approach, which should be working otherwise, when you want to create a patient waiting document, use .set instead of .add, and set the document id to your pateint's email, like this:
Firestore.instance
.collection("Doctors")
.document(doctorEmail)
.collection("paitents_waiting")
.document(paitentEmail)
.set({your patient data here});
This should get things working for you.
To delete all patients for a doctor by the email you can use a combination of Firestore query and batch updates. The first one we need to get all patients with the same email and the other to delete them. A function for that would look like this:
Future<void> deletePatiensForDoctor(String docEmail, String patEmail) async {
WriteBatch batch = FirebaseFirestore.instance.batch();
QuerySnapshot querySnapshot = await Firestore.instance
.collection("Doctors")
.document(docEmail)
.collection("paitents_waiting")
.where('email', isEqualTo: patEmail)
.get();
querySnapshot.docs.forEach((doc) {
batch.delete(doc.reference);
});
return batch.commit();
}

Deleting a Firestore entry based on FIFO

I'm trying to create a script that deletes a record from a Firestore collection using a FIFO (First In First Out approach).
So if there are three matching results in the collection, the script should take the first one added and just delete that one (leaving the remaining two). My code is:
_firestore
.collection('myCollection')
.where('uid',
isEqualTo: _auth.currentUser.uid)
.where('field',
isEqualTo: widget.field)
.orderBy('Posted', descending: false)
.limit(1)
.get()
.then((querySnapshot) {
querySnapshot.docs
.forEach((documentSnapshot) {
_firestore
.collection('myCollection')
.doc(documentSnapshot.id)
.delete();
});
});
(Just to note: 'Posted' is the date the entry was added) Unfortunately this doesn't work, and all three results remain in the collection.
If though I use this script instead, then all three results are removed from the collection:
_firestore
.collection('myCollection')
.where('uid',
isEqualTo: _auth.currentUser.uid)
.where('field',
isEqualTo: widget.field)
.get()
.then((querySnapshot) {
querySnapshot.docs
.forEach((documentSnapshot) {
_firestore
.collection('myCollection')
.doc(documentSnapshot.id)
.delete();
});
});
An example of an entry in my collection is as follows:
So I know the logic, connection, fields etc... are all correct, but why does the first example not work?
Have you check you logs? I am pretty sure that Firebase is throwing an error saying that your collection need indexes with a link.
Just follow the link and the instruction to build the indexes. Once complete you should be able to do what you are looking for.
More info about Indexes: https://firebase.google.com/docs/firestore/query-data/indexing
and Simple queries / Coumpound queries: https://firebase.google.com/docs/firestore/query-data/queries

Search for data/values/keyes in firestore documents

I have a search screen in my app and i want to make sure you can search for every value in a firestore document. There are always 4 Keys in one document: title, author, genre and code.
getBookbyTitel(query) async{
return await Firestore.instance
.collection("book")
.where("titel", isEqualTo: query)
.getDocuments();
}
but with this code, I am only able to search for the title. how can I search for the three other keys a well?
Thanks
getBookbyTitel(query) async{
return await Firestore.instance
.collection("book")
.where("titel", isEqualTo: query).where("author", isEqualTo: query2).where("genre", isEqualTo: query3).
where("code", isEqualTo: query4).getDocuments();
}
Firestore has the advantage of having indexes complex and simple.
getBookbyTitel(query,query2,query3) async{
return await Firestore.instance
.collection("book")
.where("genre", isEqualTo: query)
.where("title", isEqualTo: query2)
.where("code", isEqualTo: query3)
.getDocuments();
There is no actual limit to how many .where() you can use, however this is what is called a "complex query" and as such the first time will fail because firestore needs to index first.
So, first run the code above, in the console an error message will pop up with a url that will send you to your firebase project and then on its own it will start indexing so the next time you run that code it will do it lightning fast.
However there is a downside, for each .where() you use, an additonal indexation will be needed for it to work properly. Have in mind that the order is important too, if you query in order [title,author,genre,code] you should always do it this way, otherwise it will detect it as a completely different query and will ask you to index again.
Finally there is also the issue that for example a more specific query is not the same as a query with less attributes. i.e:
getBookbyTitel(query,query2,query3) async{
return await Firestore.instance
.collection("book")
.where("genre", isEqualTo: query)
.where("title", isEqualTo: query2)
.where("code", isEqualTo: query3)
.getDocuments();
If you have this query, and then you try this instead:
getBookbyTitel(query,query2,query3) async{
return await Firestore.instance
.collection("book")
.where("genre", isEqualTo: query)
.where("title", isEqualTo: query2)
.getDocuments();
It won't work, it will ask you for another index.