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来获得你想要的行为:
-
使用Firebase查询获取正确的数据,然后在客户端重新sorting
-
添加一个具有递减值的字段到数据
对于后一种方法,通常具有倒置的时间戳。
-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 })