Manish Patiyal
Manish Patiyal

Reputation: 4477

OrderByChild() not working in Android Client

In my android application I am using following code

 FirebaseDatabase database = FirebaseDatabase.getInstance();

    ref = database.getReference().child(Keys.CONTACTIFY_CONTACTS).child(sharedPrefs.getString(SharedPreferenceValues.CURRENT_USER_UID, "")).child(Keys.SHARED_CONTACTS);
    refer = ref.orderByChild(Keys.TIME);
 refer.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                ArrayList<HashMap<String, Object>> sharedList = new ArrayList<HashMap<String, Object>>();
                if (dataSnapshot.getValue() != null) {
                    Object[] rootData = ((HashMap<String, Object>) dataSnapshot.getValue()).values().toArray();
                    for (Object singleElement :
                            rootData) {
                        HashMap<String, Object> eachElement = (HashMap<String, Object>) singleElement;
                        sharedList.add(eachElement);
                    }
                    recyclerView.setAdapter(new SharedItemsRecyclerViewAdapter(sharedList, mListener, getActivity()));
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

My firebase database structure is

enter image description here

My Firebase rules relevant to scenario are

    {
  "rules": {
  "mapper":{
       ".read": "auth!= null",
         ".write": "auth!= null"
    },
      "share_id_mapper":{
       ".read": "auth!= null",
         ".write": "auth!= null"
    },
       "contactify_contacts":{
                       //can read a message if authenticated
                 "$uid": {
                    "shared_contacts": {".indexOn": "time",
                            ".write": "auth!= null",

Problem is that I am getting the hasmap from snapshot in default sorted way i.e. the sortbyKey(). But I am expecting the result based on the value of time key in the node data.

Upvotes: 1

Views: 1968

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 600116

When you execute a query against the Firebase Database, the DataSnapshot it returns contains the keys, the values and the order of the results.

But then you convert the snapshot to a Map:

((HashMap<String, Object>) dataSnapshot.getValue())

At this point the Firebase client has no other option than to drop the information about the order of the results.

The solution to this is to iterate over the snapshot's children with the methods from DataSnapshot and only then convert the values:

public void onDataChange(DataSnapshot dataSnapshot) {
    List<String, Object> data = new ArrayList<String,Object>();
    for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
        data.add(childSnapshot.getKey(), childSnapshot.getValue());
    }
}

We recently added a sample of this to our query documentation.

Upvotes: 2

Related Questions