我有一个方法可以初始化我的字段变量 currentTask
。我不明白为什么我无法从 firebase 读取我的对象。方法如下:
private void getCurrentTask() {
final DatabaseReference dRef1 = database.getReference().child("Users").child(uid).child("CurrentTask");
dRef1.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
currentTask = dataSnapshot.getValue(CurrentTask.class);
} else {
Toast toast = Toast.makeText(TasksListActivity.this, "no magic", Toast.LENGTH_LONG);
toast.show();
}
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
if (currentTask == null) {
Toast toast = Toast.makeText(this, "magic)", Toast.LENGTH_LONG);
toast.show();
}
}
Toast no magic
从未出现,所以对象存在。但是,在 toast 方法的末尾 magic
出现了,这意味着 currentTask == null
。即使在初始化之后!
这是我的数据库:
最佳答案
@Roasario和 @ReazMurshed的回答都是对的。但是让我通过描述您的代码如何不按您的预期工作来使其更简单:
private void getCurrentTask() {
...
dRef1.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
... (point 1)
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
... (point 2)
}
Firebase 数据库异步加载您的数据。这意味着(为简单起见)获取数据的过程不会干扰您的主进程。考虑到这一点,(point 2)
中的代码并不总是在 (point 1)
中的代码之后执行,反之亦然。虽然通常 (point 1)
中的代码在 (point 2)
之后执行,但并不总是这样。因此,您应该考虑到您在 (point 1)
中编写的代码可以随时执行。
那么你应该用那个概念来写你的代码。这意味着如果你想对 (point 1)
中的变量做任何事情(比如用 dataSnapshot 值填充 currentTask 然后检查它是否为 null),你应该把它全部放在 (point 1)中)
希望这对您有所帮助。
关于java - Firebase 阅读问题。对象始终为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41504585/