Firebase Data Desc在Android中sorting

我search了所有的互联网,Firebase的API,所以无法find我的问题的答案。

我正在将数据存储在Firebase存储中。

对象具有属性timestamp Comment 。 当我将数据从设备推送到Firebase时,我使用currentTime填充timestamp并存储为long数据types。

当我使用firebaseRef.orderByChild("timestamp").limitToLast(15)检索数据时, firebaseRef.orderByChild("timestamp").limitToLast(15)结果没有按照我的预期sorting。

我甚至玩过规则,没有结果:

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

我试图在String数据types的存储timestamp ,同样的问题。

感谢帮助。

Firebase可以按给定属性升序排列项目,然后返回前N个项目( limitToFirst() )或最后N个项目( limitToLast() )。 没有办法表明你想要降序的项目。

有两种select来获得你想要的行为:

  1. 使用Firebase查询获取正确的数据,然后在客户端重新sorting

  2. 添加一个具有递减值的字段到数据

对于后一种方法,通常具有倒置的时间戳。

 -1 * new Date().getTime(); 

我发现,如果您使用回收站视图来呈现该数据,一个很好的解决scheme…

 mLayoutManager = new LinearLayoutManager(getActivity()); mLayoutManager.setReverseLayout(true); mLayoutManager.setStackFromEnd(true); // And set it to RecyclerView mRecyclerView.setLayoutManager(mLayoutManager); 

它会反转数据呈现…

 private static class ChatMessageViewHolder extends RecyclerView.ViewHolder { TextView messageText; TextView nameText; public ChatMessageViewHolder(View itemView) { super(itemView); nameText = (TextView)itemView.findViewById(android.R.id.text1); messageText = (TextView) itemView.findViewById(android.R.id.text2); } } FirebaseRecyclerViewAdapter<ChatMessage, ChatMessageViewHolder> adapter; ref = new Firebase("https://<yourapp>.firebaseio.com"); RecyclerView recycler = (RecyclerView) findViewById(R.id.messages_recycler); recycler.setHasFixedSize(true); ////////////////////////////////////////////////////////// mLayoutManager = new LinearLayoutManager(getActivity()); mLayoutManager.setReverseLayout(true); mLayoutManager.setStackFromEnd(true); recycler.setLayoutManager(mLayoutManager); ///////////////////////////////////////////////////////// adapter = new FirebaseRecyclerViewAdapter<ChatMessage, ChatMessageViewHolder>(ChatMessage.class, android.R.layout.two_line_list_item, ChatMessageViewHolder.class, mRef) { public void populateViewHolder(ChatMessageViewHolder chatMessageViewHolder, ChatMessage chatMessage) { chatMessageViewHolder.nameText.setText(chatMessage.getName()); chatMessageViewHolder.messageText.setText(chatMessage.getMessage()); } }; recycler.setAdapter(mAdapter); 

我已经通过扩展FirebaseListAdapter和覆盖getItem方法来解决问题:

 public abstract class ReverseFirebaseListAdapter<T> extends FirebaseListAdapter<T> { public ReverseFirebaseListAdapter(Activity activity, Class<T> modelClass, int modelLayout, Query ref) { super(activity, modelClass, modelLayout, ref); } public ReverseFirebaseListAdapter(Activity activity, Class<T> modelClass, int modelLayout, DatabaseReference ref) { super(activity, modelClass, modelLayout, ref); } @Override public T getItem(int position) { return super.getItem(getCount() - (position + 1)); } 

}

我没有看到任何选项来扭转数据。 但一个蛮方法就是获取数据。

 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(); } 

基于@Monet_z_Polski的方法

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

不会自动更新FirebaseRecyclerView(PopulateViewHolder不会在实时更改中触发),会产生奇怪的效果。 所以,最好的select是使用否定键来索引数据

在客户端sorting很简单,不需要更多的系统资源。 每个数据快照都有previousChildkey字段。 如果你想descsorting,想象previousChildkey是nextChildKey。 这是我的示例:

 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); } } } 

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