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
值时,无法获得实际值。
- Firebase / Android:将检索到的值从Firebase添加到arraylist会返回空指针exception
- FirebaseRecyclerAdapter无法填充结果
- 在Android Firebase存储中上传文件后如何获取文件下载Url? getDownloadUrl()不起作用
- Android – Firebase – 不同类型的用户登录
- 如果app在后台,如何使用fcm从服务器发送数据?
- 我对托管Java Web应用程序有何不理解?
- Firestore:查询android中数组中的所有元素
- Firebase电子邮件和密码validation与Android – 用户注册
- JsonMappingException:找不到合适的构造函数