【问题标题】:Firebase database not retrieving dataFirebase 数据库未检索数据
【发布时间】:2016-06-30 02:47:02
【问题描述】:

这是我第一次使用 firebase,我有一些方法都包含在同一个类中,但它们并不能正常工作。 nameExists 总是返回 false,即使我可以在控制台中看到 name 存储的值不为空。 userStatus 是此类中的 DataSnapshot 字段。

public Boolean nameExists(String name){
    if (getUserStatus(name) != null){
        return true;
    } else{ return false; }
}

 public String getUserStatus(String name){
    DatabaseReference tmpRef = FirebaseDatabase.getInstance().getReference().child("userStatuses").child(name);
    ValueEventListener v = new statusesListener();
    tmpRef.addValueEventListener(v);
    tmpRef.removeEventListener(v);
        return userStatus;
}

 private class statusesListener implements ValueEventListener{

    public void onDataChange(DataSnapshot snap){
        userStatus = (String) snap.getValue();
    }
    public void onCancelled(DatabaseError error){
    }

}

感谢您的帮助

【问题讨论】:

    标签: android firebase firebase-realtime-database


    【解决方案1】:

    您忽略了 ValueEventListener 回调的异步特性。添加侦听器时,通常需要先从 Firebase 服务器获取值,然后才能由 onDataChange() 回调提供。回调异步触发,通常在添加侦听器后的许多毫秒。

    在您的代码中,getUserStatus() 添加statusesListener,然后将其删除并返回userStatus。所有这些都发生在onDataChage() 被触发之前,所以userStatus 的值没有改变。

    此外,添加和立即删除 ValueEventListener 不是典型的用例,并且鉴于侦听器的异步性质,可能会导致它永远不会触发。最好用Query.addListenerForSingleValueEvent()添加监听器,这样给你一次值,不需要删除监听器。

    【讨论】:

    • 但是我只需要检索一次数据,我担心这会在添加侦听器后检索数据,然后在值更改时再次检索。如果更新 userStatus 需要几毫秒,我如何知道在尝试使用 userStatus 值之前需要等待多长时间,如何实现此延迟,以及如何验证 userStatus 是否已实际更新和用户不仅失去了互联网连接或一些奇怪的情况。另外,为什么 Google 的 Firebase 指南中没有这个概念?这看起来像是要添加的重要说明,应该给出解决方法。
    • 使用addListenerForSingleEvent() 添加的监听器只会触发一次,不会用于更改。这在标题为“一次读取数据”的部分中的 the documentation 中进行了描述。关于延迟和等待,您的设计必须是事件驱动的。假设您的代码在主 (UI) 线程上运行,您不能阻塞等待异步响应。
    • 如果我不知道什么时候检索到的数据,我应该如何使用它呢?
    • 没关系,我想我已经通过使用 ASyncTask 等待响应解决了这个问题。
    猜你喜欢
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多