我已将我的代码跟踪到崩溃的根本原因,显然这个构造函数无法更新类的变量。当我试图从这个类中获取数据时,我得到空指针异常。您可以安全地假设记录已经存在于数据库中,它所要做的就是获取数据并将其放在类/对象中。我现在只想获得名称,因为我正在测试该对象是否仍然为空。
class Saver{
private String name;
// constructor of Saver class
public Saver(final String uid) {
Log.d("Saver.java","Reached here"); // this works
FirebaseDatabase.getInstance().getReference().addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(final DataSnapshot dataSnapshot) {
Log.d("Saver.java", "OnDataChange"); // does not work
if(dataSnapshot.hasChild("users/" + uid)){
LoadRecord(dataSnapshot, uid);
}
else{
// set a new record into the database
FirebaseDatabase.getInstance().getReference().child("users/" + uid).setValue(CreateNewRecord(FirebaseAuth.getInstance().getCurrentUser())).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if(task.isSuccessful()){
LoadRecord(dataSnapshot, uid);
}
else{
Log.e("Saver.java","Failed to set record in database");
}
}
});
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.e("LifeSaver.java","Error: " + databaseError.getMessage());
}
});
}
// This function loads the data into the object
private void LoadRecord(DataSnapshot dataSnapshot, String uid){
Log.d("LifeSaver.java","Uid:"+uid);
// load the existing record in the database
Saver temp = dataSnapshot.child("users/" + uid).getValue(Saver.class);
setName(temp.getName());
}
}
public void setName(String name) {
this.name = name;
}
private Saver CreateNewRecord(FirebaseUser firebaseUser){
Saver saver = new Saver ();
saver.setName(firebaseUser.getDisplayName());
Log.d("saver","saver name: " + saver.getName());
return continuLifeUser;
}
显然,在数据库发生变化之前,onDataChange函数不会运行。
DataSnapshot
吗?如果是这样,怎么样? (请显示代码,以便我可以看到您正在解释的内容)编辑1: 这是构造函数中应该调用FirebaseDatabase的logcat语句:
D/Saver.java: Reached here with hA4hZrBieISwMOZaMYe7m6K5tpI3
I/DynamiteModule: Considering local module com.google.android.gms.firebase_database:4 and remote module com.google.android.gms.firebase_database:6
I/DynamiteModule: Selected remote version of com.google.android.gms.firebase_database, version >= 6
I/art: DexFile_isDexOptNeeded failed to open oat file '/data/dalvik-cache/x86_64/data@data@com.google.android.gms@app_chimera@m@00000004@DynamiteModulesC_GmsCore_prodlmp_alldpi_release.apk@classes.dex' for file location '/data/data/com.google.android.gms/app_chimera/m/00000004/DynamiteModulesC_GmsCore_prodlmp_alldpi_release.apk': Failed to open oat filename for reading: No such file or directory
D/Saver.java: Ended here
D/LoginAct.java: Name: null
答案 0 :(得分:1)
我通过加载屏幕解决了这个问题。我应该记得这个调用是Async,它需要一个接收器来调用放置数据的函数,然后再进行下一个活动。
private interface OnGetDataListener {
void onSuccess(DataSnapshot dataSnapshot);
void onFailure();
}
这是一个小型代码,供您在调用数据库获取数据时必须实现的侦听器。您可以查看与此类似的其他帖子。
答案 1 :(得分:0)
首先,您应该将数据添加到数据库,然后才能使用它。看起来Firebase中没有可用的数据。只需在firebase数据库中添加一个键值对,然后就会触发它。
FirebaseDatabase.getInstance().getReference().child("users/" + uid).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(final DataSnapshot dataSnapshot) {
Log.d("Saver.java", "OnDataChange"); // does not work
if(dataSnapshot!=null){
LoadRecord(dataSnapshot);
}
else{
// set a new record into the database
FirebaseDatabase.getInstance().getReference().child("users/" + uid).setValue(CreateNewRecord(FirebaseAuth.getInstance().getCurrentUser())).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if(task.isSuccessful()){
LoadRecord(dataSnapshot);
}
else{
Log.e("Saver.java","Failed to set record in database");
}
}
});
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.e("LifeSaver.java","Error: " + databaseError.getMessage());
}
});
}
// Load record should be like this...
private void LoadRecord(DataSnapshot dataSnapshot){
Log.d("LifeSaver.java","Uid:"+uid);
// load the existing record in the database
Saver temp = dataSnapshot.getValue(Saver.class);
setName(temp.getName());
}
}
答案 2 :(得分:0)
要获取users
节点下所有用户的所有名称,请使用以下代码:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("users");
ValueEventListener eventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.child("name").getValue(String.class);
Log.d("TAG", name);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {}
};
usersRef.addListenerForSingleValueEvent(eventListener);
输出将是:
Michael Ong
//other names
如果您只想获取特定用户的名称,请使用以下代码:
FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
String uid = firebaseUser.getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("users").child(uid);
ValueEventListener eventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = dataSnapshot.child("name").getValue(String.class);
Log.d("TAG", name);
}
@Override
public void onCancelled(DatabaseError databaseError) {}
};
uidRef.addListenerForSingleValueEvent(eventListener);
输出只是一条记录:
Michael Ong