我知道这已被问过100次,但似乎没有一个解决方案适合我。
想要阅读" user_preferences"的数据库对于已登录的用户(userID)并读取性别/年龄/体重/身高值并将其存储在下面显示的变量中。当前在所有内容(日志语句和值)上返回null。感觉我没有正确设置路径或其他东西。帮助会很棒!
和我的代码
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
myRef = mFirebaseDatabase.getReference();
userID = mAuth.getCurrentUser().getUid();
DatabaseReference testRef = myRef.child("user_preferences");
testRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) { //loop through the firebase nodes
UserPreferences userPreferences = new UserPreferences();
userPreferences.setAge(ds.child(userID).getValue(UserPreferences.class).getAge());
userPreferences.setHeight(ds.child(userID).getValue(UserPreferences.class).getHeight());
userPreferences.setWeight(ds.child(userID).getValue(UserPreferences.class).getWeight());
userPreferences.setGender(ds.child(userID).getValue(UserPreferences.class).getGender());
genderSet = userPreferences.getGender();
age = userPreferences.getAge();
height = userPreferences.getHeight();
weight = userPreferences.getWeight();
Log.d(TAG, "onDataChange: " + genderSet);
//
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
答案 0 :(得分:2)
这两行代码:
DatabaseReference testRef = myRef.child("user_preferences");
testRef.addValueEventListener(...)
有效地查询名为user_preferences
的整个节点。这意味着该位置的所有内容 - 所有用户。听起来这不是你想要的。如果您只想查询单个用户,则应通过向查询位置添加所需的用户ID来明确查询该用户:
DatabaseReference testRef = myRef.child("user_preferences").child(userID);
testRef.addValueEventListener(...)
此外,这些代码行让我感到困惑:
userPreferences.setAge(ds.child(userID).getValue(UserPreferences.class).getAge());
userPreferences.setHeight(ds.child(userID).getValue(UserPreferences.class).getHeight());
userPreferences.setWeight(ds.child(userID).getValue(UserPreferences.class).getWeight());
userPreferences.setGender(ds.child(userID).getValue(UserPreferences.class).getGender());
您要为要填充的每个字段反序列化UserPreferences对象,这很浪费。在我看来,你真的只想反序列化一次并记住对象:
UserPreferences userPreferences = dataSnapshot.getValue(UserPreferences.class);
答案 1 :(得分:1)
关于空值,您似乎正在使用外部字段,在Firebase至少在一秒钟后返回网络调用之前,不会设置外部字段。在此期间,您的值将为null,因此您不应将它们设置为onDataChange
之外的UI元素。
此外,当你只需要为该类调用一个getValue()
,然后为字段调用另外一个时,你会有很多获取/设置。
然后,您似乎不想循环任何内容,因此您应该从顶部引用直接访问用户节点。
例如,
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
myRef = mFirebaseDatabase.getReference();
userID = mAuth.getCurrentUser().getUid();
DatabaseReference testRef = myRef.child("user_preferences/"+userID);
// or .child("user_preferences").child(userID)
testRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
UserPreferences userPreferences = dataSnapshot.getValue(UserPreferences.class);
Log.d(TAG, "onDataChange: " + userPreferences.getGender());
// TODO: Update some UI element here
}
@Override
public void onCancelled(DatabaseError databaseError) {
// TODO: Add error handling
}
});
}
如果您只想阅读一次值,请使用testRef.addListenerForSingleValueEvent()