我将以下方法放在onCreate()
内,当应用启动它时会触发此方法。但是,当我尝试将mName
移到ValueEventListener()
之外时,它会返回null
并且应用程序崩溃了。
任何人都知道为什么会出现这个问题?
ValueEventListener postListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
UserDetails info = dataSnapshot.getValue(UserDetails.class);
Log.d(TAG, String.valueOf(dataSnapshot));
mName = info.getName();
**Log.d(TAG, mName); // HERE GET THE NAME**
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "getUser:onCancelled", databaseError.toException());
}
};
mDatabase.child("Admin")
.child("Info")
.child(uid)
.addValueEventListener(postListener);
**Log.d(TAG, mName); // HERE GET NULL**
答案 0 :(得分:2)
正如其他人所说:来自Firebase数据库的所有数据都是异步读取的。通过在代码中添加更多日志语句来最简单地看到这一点:
Log.d(TAG, "Before attaching listener");
mDatabase.child("Admin")
.child("Info")
.child(uid)
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "In listener's onDataChange");
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "getUser:onCancelled", databaseError.toException());
}
});
Log.d(TAG, "After attaching listener");
与您的预期不同,其输出为:
在附加监听器之前
附加监听器后
内部侦听器的onDataChange
处理异步行为的方法是重新构建您的问题。
现在您的代码已经编写:首先我们加载数据,然后我们记录它。
如果您将问题重新解析为:“无论何时加载数据,我们都会记录它”,您将得到如下代码:
mDatabase.child("Admin")
.child("Info")
.child(uid)
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
UserDetails info = dataSnapshot.getValue(UserDetails.class);
Log.d(TAG, String.valueOf(dataSnapshot));
mName = info.getName();
Log.d(TAG, mName);
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "getUser:onCancelled", databaseError.toException());
}
});
所以需要数据的所有代码都需要在onDataChange()
内。或者,您可以创建自己的自定义回调方法,并从onDataChange()
调用该方法。但逻辑始终是相同的:需要数据的代码在数据可用时从onDataChange()
触发。
答案 1 :(得分:1)
这是因为Firebase在您执行此操作时仍然无法检索数据:
Log.d(TAG, mName);
mName
目前为空,因为此行已在Firebase获取数据之前执行。
要解决此问题,您必须Log.d(TAG, mName)
内部 onDataChange
方法。否则,它将是null
,因为您尚未设置该值(因为Firebase仍然没有获得该值)。