I am trying to update a field of existing document in my collection in FireBase Firestore. I want to search that document using one of its field.
My collection name is "complaints",
My document's structure looks like --
complainant_Name: "XYZ"
complaint_Details : "some random details"
e_Mail: "xyz#gmail.com"
id: 5
phone_No: "1234567890"
I want to search documents and if "id" field of a document is say 5, I want to update it say change "complainant_Name" field to "ABC". How to write the code for this query in java android? I couldn't find any code source which tells how to update after searching in Firebase Firestore.
To solve this, please use the following lines of code:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference complaintsRef = rootRef.collection("complaints");
complaintsRef.whereEqualTo("id", 5).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Map<Object, String> map = new HashMap<>();
map.put("complainant_Name", "ABC");
complaintsRef.document(document.getId()).set(map, SetOptions.merge());
}
}
}
});
After using this code, the property complainant_Name will hold the value of ABC.
Related
I have my firestore collection structure as shown in the image.
Following is the main collection name which contains currently logged userId as a document ("AuScbj..")
which contains a subcollection called uIds which contains the user ids of users he follows.
When logged in user ("AuScbj..") visits a particular user profile, how can I check whether that profile user's Id available in his following list just by querying like below
firebaseFirestore.collection("Following)
.document(FirebaseAuth.getInstance().getCurrentUser().getUid())
.collection("uIds").where(
You're looking for .where(fieldPath: "uids", opStr: "array-contains", value: followingUID). It should work with your simple "array" data.
To check if id1 is present inside the uIds array in a really simpler manner, first, you should create a class:
class Document {
List<String> uIds;
}
Then get the "AUScbTj5MpNY.." document and read the content of the uIds array using the following method:
private void checkId(String id) {
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference followingRef = rootRef.collection("Following");
DocumentReference uidRef = followingRef.document(uid);
uidRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
List<String> uIds = document.toObject(Document.class).uIds;
if (uIds.contains(id)) {
//Update the UI
}
} else {
Log.d(TAG, "No such document");
}
} else {
Log.d(TAG, "get failed with ", task.getException());
}
}
});
}
Inside the onComplete, we get the array as a List and check if the id with which we are calling the method, exists inside the array. To make it work, kick it off with:
checkId(id1);
Please also note that:
firebaseFirestore.collection("Following)
.document(FirebaseAuth.getInstance().getCurrentUser().getUid())
.collection("uIds").where(/* ... /*);
Will never work, as uIds is an array inside a document and not a collection.
You can also find more info, in the following article:
How to map an array of objects from Cloud Firestore to a List of objects?
I would like to get the document id of a document which has a field that has a specific value for example in this collection, i would like to retrieve the document id of the document where the "itemName" is "eggroll.
To solve this, please try the following lines of code:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference deliveryRef = rootRef.collection("delivery");
Query nameQuery = deliveryRef.whereEqualTo("itemName", "eggroll");
nameQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Log.d(TAG, document.getId());
}
}
}
});
The output in your logcat will be the following document id:
8jy6 ... fcrm
You need to perform a simple query like the one mentioned here.
Execute it. And the document.getId() which will give you the ID of the document matching the query criteria.
I'm working on an app that uses a firestore database with the following hierarchy:
parent_collection:
parent_document:
subcollection:
child_document{
string name}
using collectionGroup I've been able to query subcollection for documents with a certain name, but I don't know how to get the parent_document
db.collectionGroup("subcollection").whereEqualTo("name", searchText).get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful()){
//here I want to get the parent id of all results
}
}
});
What is the best way to achieve that?
The QuerySnapshot points to a number of QueryDocumentSnapshot instances.
From a QueryDocumentSnapshot, you can get the collection it's from with:
snapshot.getRef().getParent()
And then the parent DocumentReference is:
snapshot.getRef().getParent().getParent()
So to get a subscollection of the parent document with:
snapshot.getRef().getParent().getParent().collection("name_of_subcollection")
Yes, I agree... that could've been a bit more readable. :)
You can write like this
List<DocumentSnapshot> documentSnapshotList = value.getDocuments();
for (DocumentSnapshot documentSnapshot : documentSnapshotList) {
DocumentReference dr = documentSnapshot.getReference().getParent().getParent();
// or any field documentSnapshot.get(field);
assert dr != null;
));
} //for end
In case you use stream:
docs = db.collection_group(u'collection_name').stream()
for doc in docs:
path = doc.reference.path # will get you the full path
# then you can manage the path as string
sub_path = path.split('/')[1]
You can get documents of a collection like this:
if(task.isSuccessful()) {
List<DocumentSnapshot> documents = task.getResult().getDocuments();
for(DocumentSnapshot documentSnapshot : documents) {
documentSnapshot.getId();
// or any field documentSnapshot.get(field);
}
}
Firestore database image
Hello, I just tried to use Firestore. I had some problem when getting document id.
The question is, I want to get a document id (red box) which has value (blue box) in it.
I use the following query:
collection("mychannel").whereEqualTo("74wRU4xHrcV9oWAXEkKeRNp41c53")
But did not give results.
Thanks!
As in the official documentation:
Although Cloud Firestore can store arrays, it does not support querying array members or updating single array elements.
So there is no way in which you can use the following query:
collection("mychannel").whereEqualTo("74wRU4xHrcV9oWAXEkKeRNp41c53")
If you only want to get the entire userId array you need to iterate over a Map like this:
collection("mychannel").document("1fReXb8pgQvJzFdzpkSy").get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
Map<String, Object> map = document.getData();
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getKey().equals("userId")) {
Log.d("TAG", entry.getValue().toString());
}
}
}
}
}
});
But note, even if userId object is stored in the database as an array, entry.getValue() returns an ArrayList, not an array.
So the output will be:
[74wRU4xHrcV9oWAXEkKeRNp41c53]
A better approach will be if you consider this alternative database structure, where each user id is the key in a map and all values are true:
userId: {
"74wRU4xHrcV9oWAXEkKeRNp41c53": true,
"AdwF...": true,
"YsHs...": true
}
This question is answered here: Firestore: Query by item in array of document
In summary, don't use arrays to store data in Firestore as the query you are trying to do is not available yet (remember it is still in beta). You should use a Map instead.
I'm Trying to build a restaurant app using firestore to store the orders and the users.
I tried 2 methods, first one was to write the ArrayList of orders as a Array in firestore database, but coudn't read them afterwards...
I used DocumentSnapshot.toObject(myclassoflist.class) but this only worked with no array list in the document, only with values = ".."
Then I created a collection of documents (each document is an item) which contains the array as simple values
To understand this take a look at my database
Then, to read them i first get all the document ids
db.collection("orders").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (DocumentSnapshot document : task.getResult()) {
documentsIDs.add(document.getId());
}
Integer allIdsD = task.getResult().size();
if (allIdsD.equals(documentsIDs.size())) {
readDocs();
}
}
}
});
Then for each document id, i created 3 more db.collection(collection).get() in order to get the inside of each document within the subcollection, using again the function DocumentSnapshot.toObject(myclass.class).
The problem here is that it takes ~0.8 secs to get a complete order from the database, which is a lot considering there could be like 100+ orders per day
My project on GITHUB
Examples from: LimatexMM/app/src/main/java/g3org3/limatexmm/orders.java
EDIT:
I also tried to write the orders as follow:
orderListBig docData = new orderListBig(list, currentUser, adList, docId);
(list is ArrayList, currentUser, adList are objects)
db.collection("orderss").document(docId).set(docData)
and then read it with:
db.collection("orderss").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (DocumentSnapshot document : task.getResult()) {
orderListBig ahah = document.toObject(orderListBig.class);
allOrders.add(ahah); (ArrayList of ordersListBig)
an part of my order document
As per official documentation regarding the use of arrays in Cloud Firestore you need to know that:
Although Cloud Firestore can store arrays, it does not support querying array members or updating single array elements.
If you only want to get the entire orderList array and get the value of, let's say itemMore, you need to get the reference of that particular document and then iterate over a Map like this:
Map<String, Object> map = documentSnapshot.getData();
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getKey().equals("itemMore")) {
Log.d("TAG", entry.getValue().toString());
}
}
But note, even if orderList object is stored in the database as an array, entry.getValue() returns an ArrayList, not an array.
I better approach for your use-case, would be if you consider this alternative database structure, where each item is the key in a map and all values are true:
orderList: {
"itemMore": true,
"itemMoreValue": true,
"itemMoreOtherValue": true
}
Bafta! ;)