问题
Im creating an app with Firebase database here is my data structure:
{
"teachers" : {
"USYSacnOjDR5EAPwljZMHtggN9I2" : {
"name" : {
"teacher_name" : "Alison"
},
"members": {
"sIrfMA3bm0R9uj55nDUFpFyabcL2" : true
}
}
},
"users" : {
"sIrfMA3bm0R9uj55nDUFpFyabcL2" : {
"position" : {
"bpos" : "0"
},
"name" : {
"email" : "m@m.com",
"name" : "John",
"surname" : "Clash"
}
}
So now in RecyclerView
im trying to display all of the Alison
teacher members, as you can see John Clash
is set to true
. Anyway when i try to retrieve user this way:
reference = FirebaseDatabase.getInstance().getReference("teachers").child(teacherkey).child("members");
reference.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
User user = dataSnapshot.child("name").getValue(User.class);
result.add(user);
adapter.notifyDataSetChanged();
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
User user = dataSnapshot.child("name").getValue(User.class);
result.remove(user);
adapter.notifyDataSetChanged();
}
the app crash because of NPE, datasnapshot key is valid, it is John's account key but value of snapshot is true
. How can i solve that and get from John's data name
and surname
?
@Edit: Here is my retrieving code:
public void updateList() {
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String userId = ds.getKey();
DatabaseReference userIdRef = FirebaseDatabase.getInstance().getReference().child("users").child(userId);
userIdRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
User user = dataSnapshot.child("name").getValue(User.class);
result.add(user);
adapter.notifyDataSetChanged();
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
回答1:
To solve this, you need to query your database twice. Please see the code below:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference membersRef = rootRef.child(teachers).child(teacherId).child("members");
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String userId = ds.key();
DatabaseReference userIdRef = rootRef.child("users").child(userId);
ValueEventListener eventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
Log.d("TAG", user.getName());
}
@Override
public void onCancelled(DatabaseError databaseError) {}
};
userIdRef.addListenerForSingleValueEvent(eventListener);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {}
};
membersRef.addListenerForSingleValueEvent(valueEventListener);
回答2:
You have 2 approaches to solve this issue:
a.) Inside onChildAdded you already have, if the value you got is true, do another search in database, but this time in "users" node. Something like
newReference = FirebaseDatabase.getInstance().getReference("users").child(dataSnapshot.getKey).child("name")
b.) In the "members" node, write "John Clash" instead of "true". This approach will work for now, but you will fall into the first approach if someday you need to retrieve email address as well
来源:https://stackoverflow.com/questions/50397281/how-do-i-get-entire-object-in-firebase