Firestore - get the parent document of a subcollection - android

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);
}
}

Related

Firestore to query Array sub collection

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?

how to get the document id of a document that has a field with a specific value?

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.

How to query by type and date?

I cant get user recipe Ids to list
I try to query by whereEqualTo and orderBy but on compile firebase suggested me to create indexing, so I did that but it dont give me any results.
for (String mealType : dishTypeList){
userCollectionReference.document(userId).collection("favourites")
.whereEqualTo("mealType", mealType)
.orderBy("dateWhenSetFavourite", Query.Direction.DESCENDING)
.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
List<String> favouriteRecipeIds = new ArrayList<>();
for (QueryDocumentSnapshot document : task.getResult()){
favouriteRecipeIds.add(document.toObject(FavouriteRecipeModel.class).getRecipeId());
Log.d(TAG, "LIST LIST: " + favouriteRecipeIds);
}
myFirebaseCallBack.onSuccessCallback(favouriteRecipeIds);
}
});
}
I want to get recipeId whereEqualTo by mealType and ordered by dateWhenSetToFavourites
This is my database:
Are you sure that dishTypeList contains the same dish types that are used in the database? If yes, your code looks fine to me. If all your objects in the database contain the recipe id than the following code should work:
favouriteRecipeIds.add(document.toObject(FavouriteRecipeModel.class).getRecipeId());
Otherwise, a more simpler way of getting the document id would be:
favouriteRecipeIds.add(document.getId());
Beside that, everytime you are getting as a result a Task object, check to see if it is successful:
if (task.isSuccessful()) {
//Your logic
} else {
Log.d(TAG, task.getException().getMessage());
}
And also use the else part of the statement to check for an error message.

Firestore firebase Android search and update query

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.

SELECT where document field contains the string in Firestore?

How can I select a document in my Firestore where the value of a field contains 'pp' ;
How to add option like whereContains("title","pp") in firestore ?
firestore added multiple where cause but we need "contains" also
to improve search. Is there any alternate method available or firestore developers ignore it?
FirebaseFirestore db2 = FirebaseFirestore.getInstance();
db2.collection("products")
.whereEqualTo("cat","fruits")
.whereEqualTo("subcat","apple")
.whereEqualTo("blocked",false)
.whereContains("title","pp")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for(int i=0;i<task.getResult().size();i++){
Product product=task.getResult().getDocuments().get(i).toObject(Product.class);
Log.d(TAG+"2", product.getTitle()+"");
}
for (QueryDocumentSnapshot document : task.getResult()) {
// Log.d(TAG+"2", document.getId() + " => " + document.getData());
}
} else {
Log.w(TAG+"2", "Error getting documents.", task.getException());
}
}
});
Firestore has no method to search by substring. Your options are to mirror your data to a full text search engine such as Algolia, be clever about how you structure your data to support the specific kinds of queries that are similar to a substring search, or file a feature request.

Categories

Resources