Getting Data from Firestore Never Completes Successfully - java

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

Related

How to read a Firestore document?

I'm new to Android development ... ;-)
I need to know how to read a specific document I saved to Firestore, without having to copy the "documentPath" manually from the Cloud Firestore Console!
How do you do this automatically?
Next, I put some of the code where the documentPath is that I need to configure:
DocumentReference user = mFirestore.collection("Users").document(idUsers).collection("Companies").document(**"documentPath"**)
link to the image:
Company that I registered now and that I wish to need to show the user automatically
link to the document:
Document fields
I'm testing the following class:
private void ReadSingleEmpresa() {
FirebaseAuth autenticacao = ConfiguracaoFirebase.getFirebaseAutenticacao();
String idUsuario = Base64Custom.codificarBase64(autenticacao.getCurrentUser().getEmail());
DocumentReference user = mFirestore.collection("Users").document(idUsuario).collection("Companies").document("gaSpr59pbeMmO9UpFxQQ");//document path
user.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("ler doc", "DocumentSnapshot data: " + document.getData());
StringBuilder fields = new StringBuilder("");
//Some document fields
fields.append("Company name: ").append(document.get("nomeEmpresa"));
fields.append("\nEmail: ").append(document.get("emailRepresentante"));
fields.append("\nTelephone number: ").append(document.get("telefoneRepresentante"));
txtEmpresa.setText(fields.toString());
} else {
Log.d("ler doc", "No such document");
}
} else {
Log.d("ler doc", "get failed with ", task.getException());
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
}
This is the result:
Result of reading some document fields
It works but I do not know how to get the document I just registered among several. I only get it when I manually copy the document ID ...

Android Studio - How do I get documents from a sub-collection in Firestore?

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.

Firestore getting most liked posts

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.

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

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

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

Categories