Reputation: 1235
This kind of question is already asked and some already had answered. But I have some confusion and that why I post that question. After I read the Firebase doc about "how to structure data in firebase from here", I googled and tried to query the group list of a user (for a couple of days and still haven't got the solution).
Assume we already have the group ids that the user participated from the /users/{$user_id} node and we would like to get the group details list from /groups note by the groupd id list. For example, something like the below query.
SELECT * FROM groups WHERE key = "techpioneers" AND key = "womentechmakers";
According to google search result and stackoverflow answers, Firebase doesn't support multiple where clause. Iterating /groups/{$groud_id} node one by one to get the group detail list is also not a good approach.
Sorry for long question. Please help how to query such kind of data list with multiple keys form Firebase using Firebase android SDK.
Upvotes: 3
Views: 4679
Reputation: 1265
One of the downsides of the Firebase Realtime Database is its inflexibility with data structuring. If you want to perform queries that look at different data nodes you almost always need to denormalize your data. This has the benefit of
The downside is that:
user-by-username' or
groups-by-user`.Back to your question: Given the following table structure:
group
group1
name:"Best group"
description: "The best group"
group2:
name:"An okay group"
description: "A decent group"
user
user1
name: "User1"
user2
name: "User2"
group-by-user
user1
group1: true
group2: true
user2
group2: true
Note how I have created a new table that will associate a user to a group without having to place this info in the user table. This ensures that the user table is solely for base non-relational user information.
To query this in Java, it would look something like the following
//Get a reference to groups a user is in
//get a reference
DatabaseReference groupByUserRef = FirebaseDatabase.getInstance().getReference();
//get a reference to the join table mentioned above
groupByUserRef.child("group-by-user").child("user1").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
//This contains a list of group keys associated to the user;
Iterable<DataSnapshot> groupsByUser = dataSnapshot.getChildren();
//iterate through the list of group keys associated to the user
groupsByUser.forEach(groupDatasnapshot -> {
String groupId = groupDatasnapshot.getKey();
FirebaseDatabase groupReference;
DatabaseReference groupRef = FirebaseDatabase.getInstance().getReference();
//Once the key has been retrieved, do a search in the database to get the group
groupRef.child("group").child(groupId).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Here is where you will get the groups associated to the user.
Group group = dataSnapshot.getValue(Group.class);
//Add logic here ..
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
});
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
EDIT To conclude As mentioned above you can see it is a very convoluted approach. This is a drawback of the Realtime database. If you would like to ensure not looping over keys you have the following option.
user
table. This has the downside of you having to pull large sets of data when your group info grows (some of which you wont need).Upvotes: 3