Firebase儿童和价值听众

时间:2017-11-12 14:56:08

标签: java android firebase firebase-realtime-database

首先,我知道这个问题已被多次询问,但最近我的应用程序出现问题引起了我对此事的兴趣。我也阅读了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中的查询方法获取最后一个节点的值。这是代码片段。

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"
    }
  }
}

以下是我获取用户数据的代码片段。

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()返回null。然后,这就是我突然想要一个解释,以便向前推进,我可以更好地理解这两个听众是如何工作和选择的。

这些是我的具体问题:

  • 如果涉及查询,ChildEventListener是我选择的那个而不是替代方案吗?
  • 从上面的两个例子中,当我可以指定具有Key:Value对的节点时,似乎使用了ValueEventListener,该节点在指定节点下面一个级别。另一方面,当没有涉及Value时使用ChildEventListener,只是Childs(ChildEventListener中的" Child"是什么意思?)。我之前的发言是否正确?

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

2 个答案:

答案 0 :(得分:2)

它更加简单:ValueEventListener一次性触发整个结果,ChildEventListener分别触发结果的每个子节点。< / p>

要确定您是需要ValueEventListener还是ChildEventListener,需要考虑以下两点:

  1. 您的参考是否指向单个项目,或者它是否为列表。
  2. 是否(如果是列表)您希望单独处理每个项目,或者是否要同时处理所有项目。
  3. 如果您有一个指向单个项目的听众,则您将使用ValueEventListener

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

答案 1 :(得分:1)

  

这些是我的具体问题:

     

如果涉及查询,ChildEventListener是我选择的那个而不是替代方案吗?

     

从上面的两个例子中,我可以使用ValueEventListener来指定具有Key:Value对的节点,该节点紧跟指定节点下一层。另一方面,当没有涉及Value时使用ChildEventListener,只是Childs(ChildEventListener中的“Child”是什么意思?)。我之前的发言是否正确?

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

现在,如果涉及查询,你不能选择其中任何一个,你不必总是使用childeventListener

对于第二个问题,你说的有点真实,通常在我们用于循环的valueeventlistener中:

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

因此数据将在dataSnapshot的子节点内迭代。但是如果你使用ChildEventListener,你就不必在上面使用它。

但显然如果嵌套的更多,你必须在childeventlistener

中进行循环