问题描述
我将下面的方法放在 onCreate()
中,当应用程序启动时它会触发这个方法.但是当我尝试在 ValueEventListener()
之外获取 mName
时,它返回 null
并且应用程序崩溃了.
I put the below method inside an onCreate()
, when the app launch it will trigger this method. But when I try to to get mName
outside the ValueEventListener()
, it return null
and the app crashed.
有人知道为什么会出现这个问题吗?
Anyone know why this issue happen?
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**
推荐答案
正如其他人所说:Firebase 数据库中的所有数据都是异步读取的.通过在代码中添加更多日志语句,最容易看到这一点:
As the others have said: all data from the Firebase Database is read asynchronously. It's easiest to see this by adding some more log statements to your code:
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");
与您所期望的不同,它的输出是:
Unlike what you may expect, the output of this is:
附加监听器之前
附加监听器后
内部监听器的 onDataChange
Inside listener's onDataChange
处理异步行为的方法是重构您的问题.
The way to deal with the asynchronous behavior is to reframe your problem.
现在你的代码已经写好了:首先我们加载数据,然后我们记录它.
Right now your code is written: first we load the data, then we log it.
如果您将问题重新定义为:每当加载数据时,我们都会记录它",您会得到如下代码:
If you reframe the problem to: "whenever the data is loaded, we log it", you get code like this:
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()
当数据可用时触发.
So all code that needs the data, needs to be inside the onDataChange()
. Alternatively, you can make your own custom callback method and invoke that from onDataChange()
. But the logic is always the same: the code that needs toe data, is triggered from onDataChange()
when the data is available.
这篇关于Firebase 检索数据 Null 外部方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!