I'm developing an application for Android that uses firebase. The application has Users and each user has Friends.
users: {
one: {
name: Mark,
friends: {
two: true,
three: true
},
two: {
name: Carl
},
three: {
name: Gustav
}
}
In this example, Mark has two friends (Carl and Gustav), the other two don't have friends.
I want to get a Mark's Friends List.
String userId = "one";
DatabaseReference friendsDb = db.getReference("users").child(userId).child("friends");
final DatabaseReference usersDb = db.getReference("users");
ValueEventListener friendsListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
GenericTypeIndicator<LinkedHashMap<String,Boolean>> t = new GenericTypeIndicator<LinkedHashMap<String,Boolean>>() {};
LinkedHashMap<String,Boolean> tDataset = dataSnapshot.getValue(t);
users.clear();
for( String userId : tDataset.keySet() ) {
usersDb.child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
// how to return the user???
// users.add(user);
}
});
}
mAdapter.notifyDataSetChanged();
}
};
friendsDb.addValueEventListener(friendsListener);
Am I using a correct approach about data modeling and indexes? How is it supposed to give me back the user list that I need?
I understand that listening to a resource it is an async operation, is there a way to get the values that I need in one shot?
Any help will be appreciated! Thanks!
EDIT
Solution proposed by Frank van Puffelen it's correct in the concept but it's not correctly implemented. The concept is to call the mAdapter.notifyDataSetChanged(); when all the children has been retrieved from firebase db. But it have to check the dimension of the first snapshot, intead of the second, as below.
DatabaseReference friendsDb = db.getReference("users").child(userId).child("friends");
final DatabaseReference usersDb = db.getReference("users");
ValueEventListener friendsListener = new ValueEventListener() {
@Override
public void onDataChange(final DataSnapshot dataSnapshot) {
GenericTypeIndicator<HashMap<String,Boolean>> t = new GenericTypeIndicator<HashMap<String,Boolean>>() {};
HashMap<String,Boolean> tDataset = dataSnapshot.getValue(t);
final int usersSize = tDataset.size();
users.clear();
for( String userId : tDataset.keySet() ) {
usersDb.child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
users.add(user);
if (users.size() == usersSize) {
mAdapter.notifyDataSetChanged();
}
}
});
}
}
};
friendsDb.orderByKey().addValueEventListener(friendsListener);