Firebase: How to retrieve two values for the same key query?
You cannot use the AND
clause in firebase database, you are only able to query on one language, so you can only do:
orderByChild("language").equalTo("en")
Retrieving child value without knowing key value from Firebase realtime database
I will not know the value of the VenueID or the PushID (see below)
You need to know the value of VenueID
in order to be able to query your database at least for your the -LWLuM2nesg0uaP0dLSn
node. So the following query:
.orderByChild("drinkManufacturerID").equalTo(currentFirebaseUser.getUid())
Will only get you all the drinks that exist within that particular object.
Is it possible without restructuring my database?
No, unfortunately there is no way in Firebase to query two or more Firebase nodes, two levels deep in the tree, as you intend to. To sovle this, you should duplicate your data. This practice is called denormalization
and is a common practice when it comes to Firebase. If you are new to NoQSL databases, I recommend you see this video, Denormalization is normal with the Firebase Database for a better understanding.
Also, when you are duplicating data, there is one thing that need to keep in mind. In the same way you are adding data, you need to maintain it. With other words, if you want to update/detele an item, you need to do it in every place that it exists.
That being said, in your particular case, you should consider augmenting your data structure to allow a reverse lookup by creating another node named vanues
, where you should add as objects all corresponding drink
objects. So you database structure should look similar to this:
Firebase-root
|
--- vanues
|
--- -LZB-86uakRrWpI6VYzd (drink object)
|
--- drinkManufacturerID: "D1eY ... wrT5"
|
--- VenueID: "-LWLuM2nesg0uaP0dLSn"
Using this schema, you can simply query the database to get all drinks, where drinkManufacturerID
equal to uid
, using the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference vanuesRef = rootRef.child("vanues");
Query query = vanuesRef.orderByChild("drinkManufacturerID").equalTo(uid);
query.addListenerForSingleValueEvent(/* ... */);
If you want to get all drinks from a specific vanue, simply use:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference vanuesRef = rootRef.child("vanues");
Query query = vanuesRef.orderByChild("VenueID").equalTo(VenueID);
query.addListenerForSingleValueEvent(/* ... */);
In which VenueID
might hold a value like -LWLuM2nesg0uaP0dLSn
.
How to pull specific value from firebase
Firebase will always return full nodes. So you cannot just return the score for a user. But you can return the common node that both the score and user are under (the one starting with -K...
) by using a Firebase query:
DatabaseReference leadersRef = FirebaseDatabase.getInstance().getReference("Leaders");
Query query = leadersRef.orderByChild("uID").equalTo("vUdnKx...");
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot child: snapshot.getChildren()) {
System.out.println(child.getKey()+": "+child.child("Score").getValue(Long.class));
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "onCancelled", databaseError.toException());
// ...
}
})
Note that the code loops over the snapshot
in the result. That is because a query will potentially have multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
For more reading see the Firebase documentation on handling lists and sorting and filtering data.
Firebase Android get value by child key
That's quite possible:
DatabaseReference chatReference = FirebaseDatabase.getInstance().getReference("chats");
chatReference.orderByChild("users/user1").equalTo(true).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot chat: dataSnapshot.getChildren()) {
Log.d("TAG", chat.getKey());
Chat chat = chat.getValue(Chat.class);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
This will print:
chat1
But this approach will not scale, since you'll need to add an index for each user. To prevent this, you'll need a data structure that more closely reflects the use-case. So: if you want to show a list of the chats that the current user is in, you'll need to store precisely that: a list of the chats for each user. Alex' answer shows the most common way of storing such data.
Related Topics
How Does Swift Disambiguate Type Arguments in Expression Contexts
Covert Realm List to Realm Result
How to Grab The Parent Object from a Subview
Swift Set UIbutton Setbordercolor in Storyboard
Implementing Undo and Redo in a UItextview with Attributedtext
Shortest Code to Create an Array of Random Numbers in Swift
How to Use This Fetchrequest() in Swift
Occasional Blank Frames After Exporting Asset - Avexportsession
Uibutton Background Color Overlaps Text on Highlight
How to Refer to a Global Type from Within a Class That Has a Nested Type with The Same Name
Arkit/Scenekit on iOS 14 Throws New Warning (Metal)
Why Swift Disallows Weak Reference for Non-Optional Type
#If Canimport(Coreimage) Not Working in Swift Package Manager
Spritekit and Swiftui, Change Scene a Better Way
Extension for Array Where Element Is Optional
Continuous Rotation of Nsimageview (So It Appears to Be Animated)