I'm wondering how to retrieve the latest entry into a document in firebase using flutter?
I can see that orderBy can be used on collections which would retrieve the latest document but can't see anything to specific entries.
My data is as follows:
Current code is as follows, but obviously doesn't return the latest.
Future<DocumentSnapshot<Map<String, dynamic>>> getData() async {
var currentUser = FirebaseAuth.instance.currentUser;
return await FirebaseFirestore.instance
.collection('USER_TABLE')
.doc(currentUser!.uid)
.get();
}
Thanks!
You could try adding a timestamp field to your document, then do an orderBy timestamp in descending order, then do limit(1) - that gives you the latest value inserted.
Related
I am trying to update a field in the last document in the Firestore collection. My updating method is below:
updateHours() {
return usersRef.doc(firebaseAuth.currentUser!.uid).collection('posts')
.orderBy('datePublished', descending: true)
.limit(1).get().then((querySnapshot) {
return querySnapshot.docs.map((e) {
usersRef
.doc(firebaseAuth.currentUser!.uid).collection('posts')
.doc(e.reference.id)
.update({"totalTime": FieldValue.increment(1)});
});
});
}
This does not work. If I use .forEach(), then all documents get updated. So, how to update only the last document field?
To be able to update the totalTime field inside the last document, please use the following lines of code:
void updateHours() async{
CollectionReference postsRef = usersRef
.doc(firebaseAuth.currentUser!.uid)
.collection('posts');
QuerySnapshot query = await postsRef.orderBy('datePublished', descending: true)
.limit(1)
.getDocuments();
query.documents.forEach((doc) {
doc.reference.updateData({"totalTime": FieldValue.increment(1)});
});
}
Don't forget that Firebase APIs are asynchronous, and you need to wait for the data until it becomes available.
I want to add data and collection both I am trying like this
Future<void> createRoom(collection, docid, data) async {
await FirebaseFirestore.instance
.collection(collection)
.doc()
.set(data)
.collection('messages');
}
But its showing error The method 'collection' isn't defined for the type 'Future'.
If you are trying to set a document in a sub-collection then first create a DocumentReference to that collection and then use set():
await FirebaseFirestore.instance
.collection(collection)
.doc("doc_id")
.collection('messages')
.doc("msg_id")
.set(data)
Do note that you should pass document ID in doc() else it'll generate a random ID every time instead updating existing one.
I want to add data and collection both
You don't need to create a collection explicitly if you are not adding a document yet. It'll be created at the time you add first document in collection. So try refactoring the code as shown below:
Future<void> createRoom(collection, docid, data) async {
await FirebaseFirestore.instance
.collection(collection)
.doc("doc_Id")
.set(data);
// simply add a document in messages sub-collection when needed.
}
Also checkout: How to create collection in Cloud Firestore from Javascript?
im trying to restore a document that its field "email" equal to certain value my code didnt get me anything dont know what is the problem
void EditDisplayedName(String email, String name) async {
CollectionReference s = FirebaseFirestore.instance
.collection("Users")
.doc("list_instructors")
.collection("Instructor")
..where("Email", isEqualTo: email);
s.doc(email).update({'Full Name': name});
} //end method
Your code doesn't yet find/read the document for the email address.
The correct process is:
// 1. Create a reference to the collection
CollectionReference s = FirebaseFirestore.instance
.collection("Users")
.doc("list_instructors")
.collection("Instructor")
// 2. Create a query for the user with the given email address
Query query = s.where("Email", isEqualTo: email);
// 3. Execute the query to get the documents
QuerySnapshot querySnapshot = await query.get();
// 4. Loop over the resulting document(s), since there may be multiple
querySnapshot.docs.forEach((doc) {
// 5. Update the 'Full Name' field in this document
doc.reference.update({'Full Name': name});
});
i want to update all document field value together not one by one.
example. in this pic i want to update thumb value in hello.
i also try but value not updated.
FirebaseFirestore.instance
.collection('tbl_Messages')
.doc("e5df2a37-816b-4b48-830f-d6387cc4d043")
.collection('e5df2a37-816b-4b48-830f-d6387cc4d043')
.orderBy('createdAt', descending: true)
.get()
.then((QuerySnapshot documentSnapshot) {
List<QueryDocumentSnapshot> queryDocumentSnapshot =
documentSnapshot.docs;
queryDocumentSnapshot.forEach((element) {
Map<String, dynamic> message =
element.data() as Map<String, dynamic>;
message['thumb'] = 'hello';
print("thumb value => ${message['thumb']}");
});
});
What you are doing is fetching the data from firebase but changing variable value locally. You cant just change the variable value and expect your database to update. You need to perform a .update() on the document. Info on how to update a document on CloudFirestore https://firebase.flutter.dev/docs/firestore/usage/#updating-documents
I would like to update a sub-collection document that I got by sending a group-query with Flutter. To my current understanding with a group-query I do not really know the parent of a sub-collection.
In order to do so, I need the document id of the parent document. The update query would then look like the following:
collection(collectionName)
.document(parentDocumentId)
.collection(subCollectionName)
.document(subCollectionDocumentId)
.updateData(someMapWithData);
Is it necessary to save the parentDocumentId within the sub-collection document to be able to do such update or is there another way to do so?
If you want to update a document inside a subcollection, then you need both the top document id and the document id inside the subcollection.
Is it necessary to save the parentDocumentId within the sub-collection document to be able to do such update or is there another way to do so?
No, its not necessary, but if you have the parentDocumentId, and you dont have the subDocumentId, then you need to query to retrieve it:
Firestore.instance
.collection("path")
.document("docPath")
.collection("subCollection")
.where("name", isEqualTo: "john")
.getDocuments()
.then((res) {
res.documents.forEach((result) {
Firestore.instance
.collection("path")
.document("docPath")
.collection("subCollection")
.document(result.documentID)
.updateData({"name": "martin"});
});
});
Unfortunately, I couldn't find an option to do this more cost-efficient. With this method, you have 1 read and 1 write operation.
Code for the following storage structure: users/${uid}/collection/$documentName/
static Future updateSubData(String uid, String mainCollection,
String subCollection, Map<String, dynamic> json) async {
//get document ID
final querySnapshot = await fireStoreInstance
.collection(mainCollection)
.doc(uid)
.collection(subCollection)
.limit(1)
.get();
//document at position 0
final documentId = querySnapshot.docs[0].id;
//update this document
await fireStoreInstance
.collection(mainCollection)
.doc(uid)
.collection(subCollection)
.doc(documentId)
.update(json);
}
I case you have more documents in the subcollection you need to remove .limit(1) so you get all documents.