I'm making a simple app in which I want to introduce most liked posts. I'm using Cloud Firestore. My question is how the query should look like in this case? (I'm using Java)
Here's the Firestore tree:
-ROOT
--Posts
---Post
----Likes
Likes collection is set of users' ids.
Assuming that the Likes property is of type number and not String, please use the following code:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
DocumentReference ref = rootRef.collection("Posts").document("Post");
ref.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
long numberOfLikes = document.getLong("Likes");
Log.d(TAG, String.valueOf(numberOfLikes));
} else {
Log.d(TAG, "No such document");
}
} else {
Log.d(TAG, "get failed with ", task.getException());
}
}
});
The output in your logcat will be the number of likes.
Related
I'm new to NoSQL databases, but I'm attempting to use Firestore with an Android mobile application I'm developing.
I can write to the DB without any issues, but I can't read data. See code below:
DocumentReference docRef = db.collection("users").document("abc#gmail.com");
docRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
User userFromDB = documentSnapshot.toObject(User.class);
}
});
When I was debugging, program execution didn't enter the 'onSuccess' function.
The code I'm using is based off the documentation (Get Data with Cloud Firestore - Custom Objects). I made sure that the 'User' fields in my code match the ones in the DB, and they all have 'get' methods.
Also, these are my rules:
match /{document=**} {
allow read, write: if true
}
I've been stuck on this for a while, any help would be highly appreciated.
The onSuccessListener is for write actions to the database. For getting data you need to use the onCompletedListener as shown in the official documentation:
DocumentReference docRef = db.collection("users").document("abc#gmail.com");
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
Log.d(TAG, "DocumentSnapshot data: " + document.getData());
} else {
Log.d(TAG, "No such document");
}
} else {
Log.d(TAG, "get failed with ", task.getException());
}
}
});
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.
I would like to get documents in a sub-collection where the date=DATE and title=TITLE in a document. I'm using date and title as primary keys so that I can display information from the documents from sub-collection "bulletin". How would I do that in Android Studio?
Or would it be better to use a different structure?
Thanks!
Image - Firestore Structure
To solve this, please use the following lines of code:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference bulletinRef = rootRef.collection("bulletin");
bulletinRef.whereEqualTo("date", date).whereEqualTo("title", title).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.getString("title"));
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
The result in your logcat will be, all titles from all documents within your bulletin collection.
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());
}
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());
}
}
});