I have the following DB structure, then I need get data filtered by "date" field. How do I do that?
root {
places {
$placeUid {
$bookingUid {
date: String
name: String
}
}
}
}
My query looks like that, and it doesn't work:
refPlaces = Firebase.database.getReference("places")
refPlaces.orderByChild("date").equalTo("14.10.2020").addValueEventListener(…)
Firebase queries work on a flat list of child nodes, where the value you order/filter on is in a fixed path under each direct child node. Since you have two dynamic levels under places, you won't be able to query for it.
The solution is to create a flat list of bookings for this use-case, with each booking then having the place Uid as a property in each booking.
For more on this, see:
Firebase Query Double Nested
Firebase query if child of child contains a value
Related
So suppose I am building an app that lets users manage trips. When a trip is created , any number of users can be added in it. I want this data to be stored in a single place and then for each user be able to retrieve the trips that that person is included in. My data looks like this:
-trips
-<trip-id>
-title
-budget
-etc
-people
-<person-id>
-name
-uid
-<person-id>
-name
-uid
-<trip-id>
-
-
-
This trip will contain all the trips created by all the users. To show any person their trips, I want to retrieve only the lists that person exists in.
This is what I've tried to do including other similar approaches.
rootReference.child("trips").orderByChild("uid").equalTo(FirebaseAuth.instance.currentUser.uid).addValueEventListener(object:ValueEventListener){
override fun onDataChange(snapshot: DataSnapshot) {
//this should only return the trips that current user exists in.
}
}
I have checked the documentation for searching and filtering on firebase but there is nothing that show filtering based nested keys. One particular example is this. I understand it perfectly. If for example I try to filter my trips based on the main attributes like title, budget, it works, but not when I use an attribute of a nested child.
What other approach can I use to filter based to nested keys or should I structure the data differently? Any help is greatly appreciated.
Firebase Realtime Database queries operate on a flat list of child nodes directly under the path that you query.
So the value you order/filter on has to be at a fixex path under each immediate child node. Since that isn't the case for your uid, you can't query across all trips for the UID of all users of those trips.
You can query across one trip for a UID of a user (and then get back that user), or you can query across all trips for properties of the trip itself, such as its title or budget.
If you want to query across all users on all trips, consider keeping an additional list where you have the UID of the user as the key, and then all their trips under there:
"user_trips": {
"uid1": {
"tripid1": true,
"tripid2": true
},
"uid2": {
"tripid2": true,
"tripid3": true
}
}
Also see:
Firebase Query Double Nested
Firebase query if child of child contains a value
Many to Many relationship in Firebase
Let's say my current structure firebase realtime database:
{
chatRooms:{
chat1:{
participants:{
user1-id:true,
user2-id:true
}
participantsCount:2,
lastTimeUpdated: {TIMESTAMP},
chatRoomName:"A chatroom",
maxParticipantsCount:10
}
}
users:{
user1-id:{
name:user1-name,
email:user1-email
}
user2-id:{
name:user2-name,
email:user2-email
}
}
}
I need to display all chatrooms that contains a specific user along with all its information, and my solution now is:
#userId is currently authenticated, firebase user.
ref.child("chats").orderByChild("/participants/"+userId).equalTo(true)
which returns the list of chats containing $userId which equals to true, along with additional information to display to the user. Is there any possible way to change this query AND/OR database structure to support optimal indexing? If I wanted to add indices, it would be something like:
chatrooms:{
participants:{
indexOn:"user1-id","user2-id"
# number of ids grows as participants increase
# Not only that, I will have to add one by one manually.
}
}
How can I add indices and also at the same time do a query in Android that will display all chatrooms that a user belongs to along with their information?
AFAIK, I cannot "loop" over the keys of the child in Android
To loop over the children of a snapshot in Android do:
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
System.out.println(childSnapshot.getKey());
}
Relevant section in the docs: https://firebase.google.com/docs/database/android/lists-of-data#listen_for_value_events
If you're asking how to display the information about each chat room that a user is in, that will take a client-side join like this:
firebase.database().ref("userChatrooms").child(firebase.auth().currentUser.uid).once(function(roomsSnapshot) {
roomsSnapshot.forEach(function(roomKey) {
firebase.database().ref("chatrooms").child(roomKey.key).once(function(roomSnapshot) {
console.log(roomSnapshot.child("name").val());
})
})
})
This type of client-side join is not nearly as slow as most developers expect, since Firebase pipelines the nested requests.
I want to perform a query to a firebase database.
My database is as follows:
I want to query "paymentStatus" by orderByChild value "paid".
How will my query code look? The below code not reading.
Query query = FirebaseDatabase.getInstance().getReference().child("Visits")
.orderByChild("paymentStatus").equalTo("Paid");
Thank you in advance.
Firebase database queries function on a list of child nodes, not on a tree. The database takes each direct child node under the location you query and then sorts/filters on the property you indicate.
There is no property paymentStatus directly under the child nodes of Visits, because the paymentStatus is one level deeper. That means that in your current data model, the query you want is not possible. If you want to filter visits by paymentStatus you will need to ensure that you have a single, flat list of visits.
Also see my answer to Firebase Query Double Nested.
I have the structure in the image below and I want to get the whole data from the node "aaa1234" querying by "id_Usuario". How can I do that query?
I tried:
DatabaseReference root = database.getReference().child("Eventos").child("participantes");
Query query = root.orderByChild("id_Usuario").equalTo(2);
Just to be more clear, the "aaa1234" is a custom key, so it will be different in the next node.
I see two mistakes.
The first one is a typo, which I already marked in my comment. You're storing the user ID as a number, so shouldn't have quotes around the value in equalTo. So: .equalTo(2)
The second mistake is in the way you try to query:
DatabaseReference root = database.getReference().child("Eventos").child("participantes");
This will create a reference to the non-existing child Eventos/participantes. What you want to do instead is query Eventos, but then against property participantes/id_Usuario. So
DatabaseReference root = database.getReference().child("Eventos");
Query query = root.orderByChild("participantes/id_Usuario").equalTo(2);
I am trying to understand how I can take a list of Ids, and then ask for Firebase to take each path and sort them by date and bring me back the top 20 all in one Firebase call. At the moment I am doing this by looping through the ids and grabbing each path - adding the items to a list then sorting them.
However this is inefficient especially as the list gets bigger.
My data looks something like this:
follows: {
UserId :{
projId1: true,
projId2: true
}
}
projects: {
projId1 :{
title: SomeText,
date: TimeStamp
}
}
A Firebase query runs at one specific location and it can only order on data that exists at fixed paths under the children of that location. There is no way to sort a Firebase query on data that exists at a different path.
So in your case, if you are loading data from /follows/$uid, there is not way to order the results on data from the /projects nodes.
That leaves you with two options:
sort the data on the client
at the sort properties to the follows children
Sorting data on the client is a valid option as long as your data set is not too large and you're not filtering too much.
But to allow sorting on the server, you'll have to duplicate the relevant properties under the node where you query:
follows: {
UserId :{
projId1: TimeStamp,
projId2: TimeStamp
}
}
projects: {
projId1 :{
title: SomeText,
date: TimeStamp
}
}
With this structure you can order then projects on timestamp with
Query query = database.child(user.getUid()).orderByValue();
query.addChildEventListener(...