【问题标题】:Firebase Child and Value listenersFirebase 子级和值监听器
【发布时间】:2017-11-12 14:56:08
【问题描述】:

首先,我知道这个问题已被多次问过,但最近我的应用程序出现的问题激起了我对这个问题的兴趣。我也阅读了 Firebase 文档。

What is the difference between ChildEventListener and ValueEventListener Firebase interfaces?

从上面的话题来看,似乎 Child 和 Event 监听器具有相同的功能但具有不同的“灵活性”,我认为这是正确的。

就上下文而言,我将提供我最近项目中的两个示例。

示例 1:

数据库结构

{
  "requests" : {
    "pushed_id_1" : {
      "request_name" : "qjvnocnqjd",
      "request_date" : "11 Oct 2017"
    },
    "pushed_id_2" : {
      "request_name" : "qjvnocnqjd",
      "request_date" : "10 Nov 2017"
    }
  }
}

参考上面的结构,我最初的计划是使用 Firebase 中的查询方法获取最后一个节点的值。这是代码的sn-p。

myRef.child("requests").orderByKey().limitToLast(1).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                Request request = dataSnapshot.getValue(Request.class);
                Log.d(TAG, "requestDate: " + request.getRequest_date());
            }

上面的代码给了我一个空值request.getRequest_date()。然后经过几次痛苦的寻找解决方案后,我找到了下面的帖子。

Retrieve null values from Firebase database Android

上面链接的 TL;DR 是解决方案是将 ValueEventListener 更改为 ChildListener ,它在我的项目中创造了奇迹。然后,是我的第二个例子。

示例 2:

数据库结构

{
  "users" : {
    "user_uid_1" : {
      "user_name" : "Admin",
      "join_date" : "7 Nov 2017"
    },
    "user_uid_2" : {
      "user_name" : "Member",
      "join_date" : "9 Nov 2017"
    }
  }
}

这是我获取用户数据的sn-p代码。

myRef.child("users").child(userID).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                User user = dataSnapshot.getValue(User.class);
                Log.d(TAG, "userDeets: " + user.getJoin_date());

                }
            }

上面的代码没有为user.getJoin_date() 返回空值。然后,这就是我突然想要一个解释,以便继续前进,我可以更好地理解这两个听众的工作方式并做出相应的选择。

这些是我的具体问题:

  • 如果涉及查询,是 ChildEventListener 是我选择的而不是替代方案吗?
  • 从上面的两个示例中,当我可以指定具有 Key:Value 对的节点时,似乎使用了 ValueEventListener 紧邻指定节点的下一级。另一方面,ChildEventListener 在不涉及 Value 时使用,只是 Childs(这就是 ChildEventListener 中的“Child”的含义?)。我这样说是否正确?

感谢您阅读本部分,如果这个问题太长,我深表歉意。

【问题讨论】:

    标签: java android firebase firebase-realtime-database


    【解决方案1】:

    更简单:ValueEventListener 一次性触发整个结果,ChildEventListener 单独触发结果的每个子节点

    要确定您需要ValueEventListener 还是ChildEventListener,需要考虑两件事:

    1. 您的参考是指向单个项目还是列表。
    2. 您是想(在列表的情况下)单独处理每个项目,还是想一次性处理所有项目。

    如果您有一个指向单个项目的侦听器,您将使用ValueEventListener

    如果您有一个指向列表的侦听器或查询,无论是否只有一个子/结果,您都需要处理该列表。您可以通过使用ChildEventListener 或在ValueEventListener.onDataChange() 中循环DataSnapshot.getChildren() 来做到这一点。

    【讨论】:

    • 一个不相关的问题,但两个听众之间是否存在内存和网络使用差异? (这与 ChildEventListener 在代码中的长度是两倍的事实不同)
    【解决方案2】:

    这些是我的具体问题:

    如果涉及到查询,是 ChildEventListener 是我选择的而不是替代的吗?

    从上面的两个示例中,当我可以指定具有 Key:Value 对的节点时,似乎使用了 ValueEventListener,该节点紧邻指定节点的下一级。另一方面,ChildEventListener 在不涉及 Value 时使用,只是 Childs(这就是 ChildEventListener 中的“Child”的含义?)。我这样说对吗?

    valueeventlistener 和 childeventlistener 有点相同,但它们与只读取一次数据的addListenerForSingleValueEvent 不同。

    现在,如果涉及查询,您可以选择两者中的任何一个,您不必总是使用childeventListener

    对于第二个问题,您所说的确实是这样,通常在 valueeventlistener 我们使用 for 循环:

      for(DataSnapshot data : dataSnapshot.getChildren()){
    

    因此数据将在 dataSnapshot 的子项中迭代。但是如果你使用ChildEventListener,你就不必使用上面的for循环了。

    但显然,如果它嵌套更多,您将不得不在 childeventlistener 中执行该循环

    【讨论】:

    • 感谢您的快速回复。根据您的回答和弗兰克的回答,根据您的解释,似乎两位听众都可以为我的两个示例工作。谢谢两位的回答!
    猜你喜欢
    • 1970-01-01
    • 2019-05-25
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    相关资源
    最近更新 更多