Firebase Data Desc Sorting in Android

2018-12-31 16:45发布

I am storing data in Firebase storage.

Object Comment with attribute timestamp. When I push data from device to Firebase I'm populating timestamp with currentTime and store in long data type.

When I do retrieving the data with firebaseRef.orderByChild("timestamp").limitToLast(15) result is not sorting how I expected.

I even played around with rules and no result:

{
    "rules": {
        ".read": true,
        ".write": true,
        ".indexOn": "streetrate",
        "streetrate": {
          ".indexOn": ".value"
        }
    }
}

I tried store timestamp in String data type, same issue.

8条回答
像晚风撩人
2楼-- · 2018-12-31 17:13

The @Monet_z_Polski approach, based on

@Override
public T getItem(int position) {
  return super.getItem(getCount() - (position + 1));
}

does have a weird effect on not update FirebaseRecyclerView automatically (PopulateViewHolder is not triggered in realtime changes). So, the best option is use a negative key to index the data.

查看更多
浪荡孟婆
3楼-- · 2018-12-31 17:13

Swift 3:

    let query = firebase.child(YourQueryPath).queryOrdered(byChild: YourQueryChild).queryLimited(toLast: YourLimit)

    query.observeSingleEvent(of: .value, with: { (snapshot) in
         // Reverse order here to get top **YourLimit** results in descending order
    })
查看更多
临风纵饮
4楼-- · 2018-12-31 17:19

Firebase can order the items in ascending order by a given property and then returns either the first N items (limitToFirst()) or the last N items (limitToLast()). There is no way to indicate that you want the items in descending order.

There are two options to get the behavior you want:

  1. Use a Firebase query to get the correct data, then re-order it client-side

  2. Add a field that has a descending value to the data

For the latter approach, it is common to have a inverted timestamp.

-1 * new Date().getTime();
查看更多
梦该遗忘
5楼-- · 2018-12-31 17:24

I don't see any option to reverse the data. But One Brute way is to get the data.

List<ModelClass> mList=new ArrayList();
public void onDataChange(DataSnapshot dataSnapshot) 
{
     mList.clear();
     for(DataSnapshot children: dataSnapshot.getChildren()){
        ModelClass modelClass=children.getValue(ModelClass.class);
        mList.add(modelClass);
     }
     Collections.reverse(mList);
     Adapter.notifyDataSetChanged();
}
查看更多
柔情千种
6楼-- · 2018-12-31 17:26

Sort at client side is simple and not require more system resources. Each data snapshot has previousChildkey field. If you want to desc sorting, imagine previousChildkey is nextChildKey. Here are my sample:

class LessonFirebaseArray<ObjectModel>{

  private ArrayList<ObjectModel> mItems;
  ...
  public LessonFirebaseArray() {
    mItems = new ArrayList<>();
  }

  public int addItem(ObjectModel item, boolean isReverse){
    int index;
    if (item.getPreviousChildKey() != null) {
      index = getIndexForKey(item.getPreviousChildKey());
      if (index < 0) {
        index = mItems.size();
      }else if(index>0 && !isReverse) {
        index = index + 1;      
      }
    }else{
      index = mItems.size();
    }
    mItems.add(index, item);
    notifyInsertedListeners(index);
    return index;
  }

  private int getIndexForKey(String key) {
    int index = 0;
    for (ObjectModel snapshot : mItems) {
      if (snapshot.getKey().equals(key)) {
         return index;
      } else {
         index++;
      }
    }
    return -1;
  }

  private void notifyInsertedListeners(int index) {
    if (mListener != null) {
      mListener.onInserted(index);
    }
  }
}
查看更多
高级女魔头
7楼-- · 2018-12-31 17:33

Sorting child items by TIMESTAMP can be done using android.support.v7.util.SortedList

  class post{
private Object time; 

public Object getTime() {
        return time;
    }

public void setTime(Object time) {
    this.time = time;
}
                        ...//rest code}

SortedList<post> data;

 data = new SortedList<post>(post.class, new SortedList.Callback<post>() {
        @Override
        public int compare(post o1, post o2) {
            Long o1l = Long.parseLong(o1.getTime().toString());
            Long o2l = Long.parseLong(o2.getTime().toString());

            return o2l.compareTo(o1l);
        }......//rest code


ref.addChildEventListener(new ChildEventListener() {
              @Override
              public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                 mSwipeRefreshLayout.setRefreshing(true);
                  post p=dataSnapshot.getValue(post.class);


                  data.add(p);



              }...// rest code

android.support.v7.util.SortedList can also be used with RecyclerView

查看更多
登录 后发表回答