我在这里创建一个使用Firebase数据库的应用程序是我的数据结构:
{
"teachers" : {
"USYSacnOjDR5EAPwljZMHtggN9I2" : {
"name" : {
"teacher_name" : "Alison"
},
"members": {
"sIrfMA3bm0R9uj55nDUFpFyabcL2" : true
}
}
},
"users" : {
"sIrfMA3bm0R9uj55nDUFpFyabcL2" : {
"position" : {
"bpos" : "0"
},
"name" : {
"email" : "m@m.com",
"name" : "John",
"surname" : "Clash"
}
}
现在在RecyclerView
我试图显示所有Alison
教师成员,因为您可以看到John Clash
设置为true
。无论如何,当我尝试以这种方式检索用户时:
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();
}
由于NPE,应用程序崩溃,数据快照密钥有效,它是John的帐户密钥,但快照的值为true
。我如何解决这个问题并从John的数据name
和surname
获得?
@Edit: 这是我的检索代码:
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) {
}
});
}
答案 0 :(得分:3)
要解决此问题,您需要两次查询数据库。请参阅以下代码:
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);
答案 1 :(得分:2)
您有两种方法可以解决此问题:
a。)在onChildAdded内你已经拥有,如果你得到的值是真的,那么在数据库中再做一次搜索,但这次是在"用户"节点。像
这样的东西newReference = FirebaseDatabase.getInstance().getReference("users").child(dataSnapshot.getKey).child("name")
b。)在"成员"节点,写" John Clash"而不是" true"。这种方法现在可以使用,但是如果有一天你需要检索电子邮件地址,你将会陷入第一种方法