Firebase将侦听器附加到Query对象

时间:2017-07-25 17:29:30

标签: android firebase firebase-realtime-database

根据Firebase documentation,将侦听器附加到数据库层次结构中的高级别是一种不好的做法。我有一个名为“地方”(非常大)的高级字段,我正在引用它。但是当我要附加监听器(ChildEventListener)时,我正在使用

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference placesReference = database.getReference("places");
placesReference.orderByChild("city").equalsTo("Madrid").addChildEventListener(....)

仅检索该城市的地点。

我的问题是 - 如果听众仅附加到<​​/ p>的地方

city = "Madrid"

或附加到整个地方级别的层次结构,因此是一种不好的做法。

修改

这是我的数据库

[...]
"places" : {
  "SomePlaceID_1" : {
      "address" : "Some address",
      "city" : "Madrid",
      "coord_latitude" : 12.122121,
      "coord_longitude" : 12.122121
  },
  "SomePlaceID_2" : {
      "address" : "Some address",
      "city" : "Madrid",
      "coord_latitude" : 12.122121,
      "coord_longitude" : 12.122121
  },
  "SomePlaceID_3" : {
      "address" : "Some address",
      "city" : "Barcelona",
      "coord_latitude" : 12.122121,
      "coord_longitude" : 12.122121
  },
  [...]
},
[...]

所以,它附加到所有地方或只有城市的地方:“马德里”

3 个答案:

答案 0 :(得分:0)

如果您使用的是placesReference.orderBy("city").equalsTo("Madrid"),则表示您的参考设置在placesReference上。如果您的数据库中只有一个名为Madrid的城市,则不需要使用orderBy()方法,只需使用以下代码行:

placesReference.child("city").child("Madrid").addChildEventListener(....)

这是绝对正确的,因为您现在在分层树中已经向下两步了。因此,在这种情况下,您只能从马德里节点获取数据。

修改

在编辑后看到你的数据库,我可以说你添加监听器的方式是非常正确的。这是使用当前数据库结构实现此目的的方法。请记住,监听器附在您放置它的确切参考上。在这种情况下,附加到所有地方(SomePlaceID_1,SomePlaceID_2等),而不仅仅是那些具有值为“Madrid”的子项的特定地方。使用.orderByChild("city").equalsTo("Madrid")只是一个订单。在值上使用此equalsTo(“Madrid”),并不意味着在那里设置了监听器。在上面解释的例子中,听众在三个中放下了两步。

您的案例中的解决方案是展平您的数据库。这意味着您需要添加另一个节点,您可以在其中仅添加马德里的那些位置。只在该特定节点上添加一个监听器。

我重新阅读了这篇文章,Structuring your Firebase Data correctly for a Complex App以便更好地理解。

希望它有所帮助。

答案 1 :(得分:0)

答案是它只附加了你把听众放在哪里。我们在下面说我的数据库。

placesReference.child("places").orderByChild("city").equalsTo("Madrid")
         .addChildEventListener(....)

如果您像这样附上听众,请等一下。

{
    "a": {
      "city": "Madrid"
    },
    "b": {
      "city": "Madrid"
    }
}

然后dataSnapshot将返回如下

SomePlaceID_1

所以问题的答案是。如果你以这种方式使用它,那么监听器将不会附加到整个层次结构。

<强>更新

您的问题:因此,它附加到所有地方或只有城市的地方:&#34;马德里&#34;?

我的回答:它仅附加到SomePlaceID_2child("city"),因为它们是"Madrid"值等于{{1}的唯一子节点}}

  "SomePlaceID_1" : {
      "address" : "Some address",
      "city" : "Madrid",
      "coord_latitude" : 12.122121,
      "coord_longitude" : 12.122121
  },
  "SomePlaceID_2" : {
      "address" : "Some address",
      "city" : "Madrid",
      "coord_latitude" : 12.122121,
      "coord_longitude" : 12.122121
  }

我们假设您将SomePlaceID_3地址更改为"Another address"。听众不会受到影响。

答案 2 :(得分:0)

例如,根引用为“ counters”

您想要计算马德里或您想要的城市的类型

databaseReference = FirebaseDatabase.getInstance().getReference().child("Countries");
    databaseReference.limitToFirst(5);

    Query query = databaseReference.orderByChild("city").equalTo("Madrid");

    ChildEventListener removedListener = query.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            if (dataSnapshot.exists()){

              long  count=  dataSnapshot.getChildrenCount();


            }


        }

        @Override
        public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            if (dataSnapshot.exists()){

                long  count=  dataSnapshot.getChildrenCount();


            }


        }

        @Override
        public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

            if (dataSnapshot.exists()){

                long  count=  dataSnapshot.getChildrenCount();


            }



        }

        @Override
        public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {


        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });