Firebase阅读问题。 对象始终为null

我有一个方法应该初始化我的字段变量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)

希望这有帮助。

请注意,onDataChange是异步的,因此if语句将始终返回false,因为您在之前未读取数据时检查它是否为null。 您应该检查onDataChange中是否为null(以确保已读取数据),如下所示:

 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); if (currentTask == null) { Toast toast = Toast.makeText(this, "magic)", Toast.LENGTH_LONG); toast.show(); } } else { Toast toast = Toast.makeText(TasksListActivity.this, "no magic", Toast.LENGTH_LONG); toast.show(); } } @Override public void onCancelled(DatabaseError databaseError) {} }); } 

修改您的参考URL有点像这样。

 final DatabaseReference dRef1 = database.getReference().child("Users").child(uid); 

现在创建一个类来表示每个节点。

 public class User { public UserCharacter Character; public UserCurrentTask CurrentTask; public String Email; public UserTasks Tasks; } 

现在你的onDataChange里面你需要这样做。

 @Override public void onDataChange(DataSnapshot dataSnapshot) { if (dataSnapshot.exists()) { User mUser = dataSnapshot.getValue(User.class); currentTask = mUser.CurrentTask; } else { // Show toast or something. } } 

正如@Roasario所说, onDataChanged函数是Async 。 因此,在检查null值时,无法获得实际值。