Firestore - How Can I Get The Collections From a DocumentSnapshot? - java

Let's say I have a userSnapshot which I have got using get operation:
DocumentSnapshot userSnapshot=task.getResult().getData();
I know that I'm able to get a field from a documentSnapshot like this (for example):
String userName = userSnapshot.getString("name");
It just helps me with getting the values of the fields, but what if I want to get a collection under this userSnapshot? For example, its friends_list collection which contains documents of friends.
Is this possible?

Queries in Cloud Firestore are shallow. This means when you get() a document you do not download any of the data in subcollections.
If you want to get the data in the subcollections, you need to make a second request:
// Get the document
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
// ...
} else {
Log.d(TAG, "Error getting document.", task.getException());
}
}
});
// Get a subcollection
docRef.collection("friends_list").get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (DocumentSnapshot document : task.getResult()) {
Log.d(TAG, document.getId() + " => " + document.getData());
}
} else {
Log.d(TAG, "Error getting subcollection.", task.getException());
}
}
});

Related

I am following the Firebase Assistant , But I am getting Errors with the given query to read data

I am trying to read data from the collection "dataToSave" , where field "Email" is equals to "test11#test11.com" , I am following the firebase assistant documentation but still getting an error.
db.collection("dataToSave")
.where("Email", "==", "test11#test11.com")
.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() + " => " + document.getData());
}
} else {
// Log.w(TAG, "Error getting documents.", task.getException());
}
}
});
I am expecting to see an output of all relevant data where email is equal to "test11#test11.com"
Image of where error is occuring
Use
db.collection("dataToSave").whereEqualTo("Email", "test11#test11.com")

How to get the id for document in collection?

how to get id for document a ?
const name=prod['categ'].value;
const a=db.collection('Categories').whereEqualTo("Name", name);
b=a.id;
You're not yet executing the query, which is necessary to get its ID.
Something like:
const query = db.collection('Categories').whereEqualTo("Name", name);
query.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());
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
The majority of that code is copied straight from the Firebase documentation on getting multiple documents from a collection, so I recommend spending some time studying that.

Firestore perform delete based on condition [duplicate]

This question already has answers here:
How to delete document from firestore using where clause
(12 answers)
Closed 9 months ago.
Is there a way I can perform a delete on Firestore documents where field1 =x and field2 = y?
I see the delete function but does not come with where.
If I use the transaction then there is get and delete but the get does not seem to accept "where" clause.
I hope I am missing something in the documentation.
Thanks
To achieve this, you need to create the desired query first and then just use the delete() method like this:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference itemsRef = rootRef.collection("yourCollection");
Query query = itemsRef.whereEqualTo("field1", "x").whereEqualTo("field2", "y");
query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (DocumentSnapshot document : task.getResult()) {
itemsRef.document(document.getId()).delete();
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
Here's my method for both querying and deleting documents from firestore. First it queries the data, then it deletes it.
Note, this method must be adapted for integer/double values.
public void whereQueryDelete(final String collection, final String field, final String value) {
mFirestoreDatabase.collection(collection)
.whereEqualTo(field, value)
.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() + " => " + document.getData());
String idDelete = document.getId();
mFirestoreDatabase.collection(collection).document(idDelete)
.delete()
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully deleted!");
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error deleting document", e);
}
});
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
}

Cloud Firestore - Access Field for Realtime Updates

I am trying to access a field labeled vote_count via Cloud Firestore realtime updates.
Below is my data structure:
Previously, under Firebase Realtime Database, I would .addValueEventListener() and drill down to the "answer." However, with Cloud Firestore, it is a bit more complex.
mStoreSelectedPollRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
#Override
public void onEvent(final DocumentSnapshot documentSnapshot, FirebaseFirestoreException e) {
if (e != null){
Log.v("LISTEN", "LISTEN_FAILED");
return;
}
if (documentSnapshot != null){
Log.v("Current Data", String.valueOf(documentSnapshot.getData()));
mStoreSelectedPollRef.collection(ANSWERS_LABEL).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
updatePollResultAnswersDynamically(task.getResult().size(), documentSnapshot);
}
});
} else {
Log.v("Current Data", "Current Data Nulll");
}
}
});
Right now, I am adding a call to .get() within my Snapshot Listener, which seems to be inefficient. I was curious how I would access the:
Total number of answer Documents.
Each individual answer
Given this snippet:
mStoreSelectedPollRef.collection(ANSWERS_LABEL).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
updatePollResultAnswersDynamically(task.getResult().size(), documentSnapshot);
}
});
You can get the total number of answer documents with:
task.getResult().size()
Since you already have this code, I'm not really sure what you're asking. If you're asking if there is a way to get the count without getting the documents, look here: https://stackoverflow.com/a/46555026
To access the individual answer documents, you loop over the query snapshot:
for (DocumentSnapshot document : task.getResult()) {
Log.d(TAG, document.getId() + " => " + document.getData());
}

How to check if Cloud Firestore collection exists? ( querysnapshot)

I'm having trouble with checking if my collections exists in Firestore database.
When I was working with Firebase Realtime database i could have used:
if(databaseSnapshot.exists)
Now with Firestore I wanna do the same.
I have already tried
if (documentSnapshots.size() < 0)
but it doesn't work.
Here is the current code:
public void pullShopItemsFromDatabase() {
mShopItemsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (DocumentSnapshot document : task.getResult()) {
ShopItem shopItem = document.toObject(ShopItem.class);
shopItems.add(new ShopItem(shopItem.getImageUrl(), shopItem.getTitle(), shopItem.getSummary(), shopItem.getPowerLinkID(), shopItem.getlinkToShopItem(),shopItem.getLinkToFastPurchase(), shopItem.getKey(), shopItem.getPrice(),shopItem.getVideoID()));
}
if (shopItems != null) {
Collections.sort(shopItems);
initShopItemsRecyclerView();
}
} else {
Log.w(TAG, "Error getting documents.", task.getException());
setNothingToShow();
}
}
});
}
the function: setNothingToShow();
Is actually what I wanna execute if my collection is empty / doesn't exists.
Please advise!
Thanks,
D.
Use DocumentSnapshot.size() > 0 to check if the collection exists or not.
Here is an example from my code:
db.collection("rooms").whereEqualTo("pairId",finalpairs)
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
if(task.getResult().size() > 0) {
for (DocumentSnapshot document : task.getResult()) {
Log.d(FTAG, "Room already exists, start the chat");
}
} else {
Log.d(FTAG, "room doesn't exist create a new room");
}
} else {
Log.d(FTAG, "Error getting documents: ", task.getException());
}
}
});
exists() applies to DocumentSnapshot while you're dealing with QuerySnapshot
Call task.result for getting QuerySnapshot out of Task<QuerySnapshot>.
From that, call result.getDocuments() and iterate through each of the DocumentSnapshot calling exists() on them.

Categories