So I'm trying to get results from firestore
db.collection("dialogs")
.whereArrayContains("members", me.getId())
.get()
.continueWith(continue -> {
List<Task<DocumentSnapshot>> tasks = new ArrayList<>();
for (DocumentSnapshot snapshot : continue.getResult())
for (Object userId : (ArrayList) snapshot.get("members"))
tasks.add(db.collection("users").document(userId.toString()).get());
return tasks;
})
.addOnSuccessListener(task -> {
for (Object something : task)
Log.d("Query", "Data: " + something);
})
.addOnFailureListener(e -> Log.d("Query", "Exception: " + e));
this code will give me the users documents as seen above, what i want as well is the document id of snapshot
To be clear, continue isn't a document, it's a Task that contains a DocumentSnapshot result. Your DocumentSnapshot is in snapshot, and you can get the id of a DocumentSnapshot using its getId() method.
val id = snapshot.getId()
Related
I have this database where I store user stuff. How do i get DataSnapshot only if uname is "user 1"
Database image here
You need to query on realtime database. You can query by giving a ref: ref('uploads'), order it by the field you want: orderByChild('uname') and then put your filter: equalTo('user 1')
firebase.database()
.ref('uploads')
.orderByChild('uname')
.equalTo('user 1')
.once('value')
.then(snap => {
snap.forEach(uploadSnap => {
console.log(uploadSnap.val());
});
})
.catch(error => {
console.log(error)
});
How do I get DataSnapshot only if uname is "user 1"
To be able to get elements from a Firebase Realtime Database where the "uname" property holds the value of "user 1", you need to use a query. To be sure that the DataSnapshot object you are looking for actually returns some results, then you should call exists(), as in the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uploadsRef = rootRef.child("uploads");
Query queryByUserName = uploadsRef.orderByChild("uname").equalTo("user 1");
queryByUserName.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot userSnapshot : task.getResult().getChildren()) {
if(userSnapshot.exists()) {
String uname = userSnapshot.child("uname").getValue(String.class);
Log.d("TAG", userSnapshot);
}
}
} else {
Log.d("TA"G, task.getException().getMessage()); //Don't ignore potential errors!
}
}
});
Since "user 1" already exists in the database, the result in the logcat will be:
user 1
I have user_info as parent collection. Under this parent collection it has single_list as child collection and some information. I want to get all values from parent collection. Please help me to find answer.
Thanks in advance
I think your use of terminology is a bit off. You have a collection of user_info documents, and each of those documents has a sub-collection named single_data.
The difference here is that there isn't a single single_data subcollection. There is one subcollection for each user_info document.
Since the subcollection has a static name, what you are looking to do is pretty straightforward using a collection group query.
firebase.firestore().collectionGroup('single_data')
.get()
.then((querySnapshot) => {
// Do something with the docs from across all the subcollections
})
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("users_info")
.get()
.addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
for (DocumentSnapshot document : task.getResult()) {
//Here you can add all documents Id to your documentIdList to fetch all sigle_data at once.
Log.d(TAG, document.getId() + " => " + document.getData());
documentIdList.add(document.getId());
}
getAllSubCollSingleData(documentIdList);
} else {
Log.w(TAG, "Error getting documents.", task.getException());
}
}
});
public void getAllSubCollSingleData(List<Int> documentIdList){
for(int i=0;i<documentIdList.size();i++){
db.collection("users_info").document(documentIdList.get(i))(would be phone number)
.collection("single_data")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
//Here you can get all documents in sub collection single_data
}
} else {
Log.w(TAG, "Error getting documents.", task.getException());
}
}
});
}}
I have made a database using Firestore.
The data base is as follows:
There is a main collection called NBDB, inside there are documents with uid for each user (for example OJQRFOyYd....). Inside each document there is another collection called MyBooks and inside this collection there are documents with uid that contain the BookID, DateCreated and Popularity.
By using the following code I have managed to obtain all of the BookIDs thank to collectionGroup query:
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collectionGroup( "MyBooks" ).get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
for (QueryDocumentSnapshot document : queryDocumentSnapshots) {
Log.d(TAG,document.getId() + " => " + document.getData().get( "BookID"));
}
}
});
However, I had like the data to be ordered by the DateCreated field.
I thought first to order the database and then to use the function above, something like:
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collectionGroup( "MyBooks" ).orderBy("DateCreated").get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
for (QueryDocumentSnapshot document : queryDocumentSnapshots) {
Log.d(TAG,document.getId() + " => " + document.getData().get( "BookID"));
}
}
});
However it is not working since my search is not inside the document of each book.
Is there a way to do it?
Thank you
Performing the get() function in security rules is not working.
It returns permission denied on the client, but passes in simulation.
The config/permissions layout is an array structure:
config/permissions-->
---------------------------> CollectionName1 :
----------------------------------------------------> 0 : UID1
----------------------------------------------------> 1 : UID2
---------------------------> CollectionName2 :
----------------------------------------------------> 0 : UID3
----------------------------------------------------> 1 : UID4
I also tried to use single key/value fields in the config/permissions as so
config/permissions-->
---------------------------> CollectionName1 : UID1
---------------------------> CollectionName2 : UID3
with the rule
allow read: if request.auth.uid == get(/config/permissions).data[c] and this passed simulation and failed on the app. If I hardcode the UID instead of request.auth.uid it gives the same result.
UID is definitely correct on the app. This was tested by using the following rule, where it passed in simulation AND the app.
allow read: if request.auth.uid == 'USER_ID_HERE'
and by comparing the logcat output of the UID to the one above.
Please help. This is the Nth day of trying to find a suitable way to structure and query Firestore. I'm certain this is an issue with either the get() call or the way I am writing the call.
Android Code:
FirebaseFirestore db = FirebaseFirestore.getInstance();
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
.setTimestampsInSnapshotsEnabled(true)
.build();
db.setFirestoreSettings(settings);
Log.d("UID", FirebaseAuth.getInstance().getCurrentUser().getUid());
DocumentReference docRef = db.collection(collection).document("X153#111");
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("FIREBASE", "DocumentSnapshot data: " + document.getData());
} else {
Log.d("FIREBASE", "No such document");
}
} else {
Log.d("FIREBASE", "get failed with ", task.getException());
}
}
});
I am using both Firebase Authentification and Firestore for my Android app. What I am trying to do is the following:
the user signs in
if it's the first time the user signs in a document named by his uid is created
if the user has already signed in before (hence document named by uid already exists) then I load some further data.
Here's my logic to solve this:
get the FirebaseUser from FirebaseAuth instance
from the FirebaseUser I get the uid
build a DocumentReference with this uid
use get() query on the DocumentReference
if DocumentSnapshot is != null then user already exists in firestore
if DocumentSnapshot == null the user doesn't exist and I create it in firestore
I was testing the code below:
FirebaseUser user = mAuth.getCurrentUser();
if(user != null) {
// get uid from user
String uid = user.getUid();
// make a query to firestore db for uid
DocumentReference userDoc = db.collection("users").document(uid);
userDoc.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document != null) {
Log.d(LOG_TAG, "DocumentSnapshot data: " + task.getResult().getData());
} else {
Log.d(LOG_TAG, "No such document");
}
} else {
Log.d(LOG_TAG, "get failed with ", task.getException());
}
}
});
}
When uid exists in firestore I get the log message with appropriate data but when it doesn't I get the following exception and I can't find a way to get to use DocumentSnapshot.exists():
java.lang.IllegalStateException: This document doesn't exist. Use DocumentSnapshot.exists() to check whether the document exists before accessing its fields.
Can anyone help me understand what I am doing wrong ?
Thanks a million ! :)
The object returned by get() is a DocumentSnapshot not the document itself. The DocumentSnapshot is never null. Use the exists() method to determine if the snapshot contains a document. If exists() is true, you can
safely use one of the getXXX() methods (in your case, getData() for a map) to obtain the value of the document.
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot snapshot = task.getResult();
if (snapshot.exists()) {
Log.d(LOG_TAG, "DocumentSnapshot data: " + snapshot.getData());
} else {
Log.d(LOG_TAG, "No such document");
}
} else {
Log.d(LOG_TAG, "get failed with ", task.getException());
}
}