火力地堡返回子节点的按键在不同设备上的/ Android的版本不同的顺序 [英] Firebase returning keys of child node in different orders on different devices/Android versions

查看:265
本文介绍了火力地堡返回子节点的按键在不同设备上的/ Android的版本不同的顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到数据的快照从我的火力地堡数据库检索用户列表,但返回的键的顺序取决于Android版/设备上使用是不同的。

有关的示范目的,我已经缩短了方法,但它基本上是如下:

 公共无效getUsers(){
    火力地堡REF =新的火力点(https://myFirebaseID.firebaseio.com);
    最后的火力地堡userRef = ref.child(用户);    userRef.addListenerForSingleValueEvent(新ValueEventListener(){
        @覆盖
        公共无效onDataChange(DataSnapshot快照){
           snapshot.toString();
        }
    });
}

这是我从调用toString()快照对象(snapshot.toString())改变顺序获得数据。

我已经尝试过了4设备。 2.运行棒棒堂(的Nexus 7 5.1.1&放大器;银河S4 5.01)以相同的顺序返回数据。而2两的其他设备(HTC感觉4.0.3和摩托罗拉G2 4.4.4)以相同的顺序(但顺序不同的设备与棒棒堂)返回数据。

有在code使用没有差别,并且在数据库中的数据是在倍完全不变时我检索到的快照。

这里是关于4.4.4和4.0.3设备上的数据顺序:

  DataSnapshot {
  键=用户,
  值= {
    114585619420240714499 = {
      ** ** userIDOfCUser = 114585619420240714499,
      ** ** NameOfCUser =测试名,
      **EmailOfCUser**=testerfireapp@gmail.com,
      ** **的朋友{=
        103902248954972338254 = {
          ** ** userIDOfFriend = 103902248954972338254,
          ** ** NameOfFriend = testName2
        }
      }
    }

这里是关于5.1.1和5.01器件的数据顺序:

  DataSnapshot {
  键=用户,
  值= {
    114585619420240714499 = {
      ** ** NameOfCUser =测试名,
      ** ** userIDOfCUser = 114585619420240714499,
      ** **的朋友{=
        103902248954972338254 = {
          ** ** NameOfFriend = testName2,
          ** ** userIDOfFriend = 103902248954972338254
        }
      },
      ** ** EmailOfCUser = testerfireapp@gmail.com
    }
  }
}

为什么数据正在交付中根据不同的Andr​​oid版本/设备上不同的订单被使用?有另一种不同的,我不知道的?

修改:
当通过如下快照迭代,按键的不同的排序仍然存在翻过不同的Andr​​oid版本:

 公共无效getUsers2(){  火力地堡REF =新的火力点(https://myFirebaseID.firebaseio.com);
  最后的火力地堡userRef = ref.child(用户);
  userRef.addListenerForSingleValueEvent(新ValueEventListener(){    @覆盖
    公共无效onDataChange(DataSnapshot快照){
        对于(DataSnapshot键:snapshot.getChildren()){
            //字符串临时存储inidividual用户的DB节点的整个儿---->它仍然会产生不同的顺序钥匙
            。字符串tempKey = keys.getValue()的toString();            //该问题仍然存在,如果我code像这样为好。
            。字符串tempKey2 = snapshot.child(keys.getKey())的getValue()的toString();        }
    }
  });
}


解决方案

有关的火力地堡的REST API包含此警告


  

在使用REST API,过滤的结果在一个未定义的顺序,因为JSON间preters不执行任何顺序返回。如果您的数据的顺序很重要,你应该在他们从火力地堡返回应用程序中的结果进行排序。


在换句话说:在一个JSON对象的属性可以在任何顺序。一个JSON解析器是免费的,因为它认为合适的方式重新排列。

您没有使用REST API,但火力地堡的Andr​​oid SDK。所有火力地堡的SDK,如果你隐藏了这样的重新排序或(下隐藏这是不可能)告诉你明确的顺序是什么(例如<一个照顾href=\"https://www.firebase.com/docs/java-api/javadoc/com/firebase/client/ChildEventListener.html#onChildAdded-com.firebase.client.DataSnapshot-java.lang.String-\"相对=nofollow> previousChildName参数来onChildAdded回调)

不过,从数据你显示它好像你正在分析从 dataSnapshot.toString输出()。虽然这是完全有效的,它意味着你选择来处理订货自己。一般来说,最好是坚持使用火力地堡Android SDK中的方法,因为它们处理像订购你的东西:

 公共无效onDataChange(DataSnapshot快照){
  为(DataSnapshot friendSnapshot:snapshot.getChildren()){
    的System.out.println(friendSnapshot.child(NameOfFriend)的getValue());
  }
}

更新

从您的更新好像你对用户的查询,然后也想遍历他们的朋友。随着Android的火力地堡API你会做到这一点与

  REF火力地堡=新火力地堡(https://myFirebaseID.firebaseio.com);
最后的火力地堡userRef = ref.child(用户);
userRef.addListenerForSingleValueEvent(新ValueEventListener(){
  @覆盖
  公共无效onDataChange(DataSnapshot userSnapshot){
    DataSnapshot friendsSnapshot = userSnapshot.child(朋友);
    为(DataSnapshot friendSnapshot:friendsSnapshot.getChildren()){
      的System.out.println(friendSnapshot.child(NameOfFriend)的getValue());
    }
  }
});

I am getting a snapshot of the data from my Firebase database to retrieve a users list, but the order of the keys being returned is different depending on the Android version/ device being used.

For demonstrative purposes I have shortened the method, but it is essentially as follows:

public void getUsers(){
    Firebase ref = new Firebase("https://myFirebaseID.firebaseio.com");
    final Firebase userRef = ref.child("users");

    userRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot snapshot) {
           snapshot.toString();
        }                                                           
    });
}

It is the data I get from calling toString() on the snapshot object (snapshot.toString()) that changes order.

I have tried it on 4 devices. The 2 running Lollipop (Nexus 7 5.1.1 & Galaxy s4 5.01) return the data in the same order. And the 2 two other devices (HTC Sensation 4.0.3 and Motorola G2 4.4.4) return the data in the same order (but a different order to devices with Lollipop).

There is no difference in the code used, and the data in the database was completely unchanged at the times when I retrieved the snapshots.

Here is the data order on the 4.4.4 and 4.0.3 devices:

DataSnapshot { 
  key = users, 
  value = {
    114585619420240714499={
      **userIDOfCUser**=114585619420240714499,
      **NameOfCUser**=testName,
      **EmailOfCUser**=testerfireapp@gmail.com,
      **friends**={
        103902248954972338254={
          **userIDOfFriend**=103902248954972338254, 
          **NameOfFriend**=testName2 
        }
      }
    }  

Here is the data order on the 5.1.1 and 5.01 devices:

DataSnapshot { 
  key = users, 
  value = {
    114585619420240714499={
      **NameOfCUser**=testName, 
      **userIDOfCUser**=114585619420240714499, 
      **friends**={
        103902248954972338254={
          **NameOfFriend**=testName2 ,
          **userIDOfFriend**=103902248954972338254
        }
      }, 
      **EmailOfCUser**= testerfireapp@gmail.com
    }
  }
}

Why is the data being delivered in different orders depending on the android version/device being used? is there another difference I am unaware of?

Edit: When iterating through the snapshot as follows, the different ordering of the keys still persists accross different versions of Android:

public void getUsers2(){

  Firebase ref = new Firebase("https://myFirebaseID.firebaseio.com");
  final Firebase userRef = ref.child("users");
  userRef.addListenerForSingleValueEvent(new ValueEventListener() {

    @Override
    public void onDataChange(DataSnapshot snapshot) {
        for (DataSnapshot keys : snapshot.getChildren()) {
            //String to temporarily store the whole child of the inidividual user's DB node ----> It still produces different order of the keys 
            String tempKey = keys.getValue().toString();

            //The problem persists if I code it like this as well. 
            String tempKey2 = snapshot.child(keys.getKey()).getValue().toString();

        }
    }
  });
}

解决方案

The documentation for Firebase's REST API contains this warning:

When using the REST API, the filtered results are returned in an undefined order since JSON interpreters don't enforce any ordering. If the order of your data is important you should sort the results in your application after they are returned from Firebase.

In other words: the properties in a JSON object can be in any order. A JSON parser is free to re-arrange them as it sees fit.

You are not using the REST API, but the Firebase Android SDK. All the Firebase SDKs take care if hiding such re-ordering from you or (when hiding it is not possible) telling you explicitly what the order is (e.g. the previousChildName argument to the onChildAdded callback)

But from the data you're showing it seems like you're parsing the output from dataSnapshot.toString(). While this is totally valid, it does mean that you're choosing to handle the ordering yourself. In general it's best to stick to using the methods of the Firebase Android SDK, since they handle things like ordering for you:

public void onDataChange(DataSnapshot snapshot) {
  for (DataSnapshot friendSnapshot: snapshot.getChildren()) {
    System.out.println(friendSnapshot.child("NameOfFriend").getValue());
  }
} 

Update

From your update it seems like you have a query on users and then want to also loop over their friends. With the Firebase Android API you'd do that with:

Firebase ref = new Firebase("https://myFirebaseID.firebaseio.com");
final Firebase userRef = ref.child("users");
userRef.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot userSnapshot) {
    DataSnapshot friendsSnapshot = userSnapshot.child("friends");
    for (DataSnapshot friendSnapshot : friendsSnapshot.getChildren()) {
      System.out.println(friendSnapshot.child("NameOfFriend").getValue());
    }
  }
});

这篇关于火力地堡返回子节点的按键在不同设备上的/ Android的版本不同的顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆