Android中的Firebase数据描述排序

知识就是力量,时间就是生命。这篇文章主要讲述Android中的Firebase数据描述排序相关的知识,希望能为你提供帮助。
我将数据存储在Firebase存储中。
对象Comment与属性timestamp。当我将数据从设备推送到Firebase时,我将使用currentTime填充timestamp并以long数据类型存储。
当我用firebaseRef.orderByChild("timestamp").limitToLast(15)检索数据时,结果不是按我的预期排序。
我甚至玩过规则而没有结果:

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

【Android中的Firebase数据描述排序】我尝试在timestamp数据类型存储String,同样的问题。
答案Firebase可以按给定属性按升序对项目进行排序,然后返回前N个项目(limitToFirst())或最后N个项目(limitToLast())。没有办法表明您希望项目按降序排列。
有两种方法可以获得您想要的行为:
  1. 使用Firebase查询获取正确的数据,然后在客户端重新排序
  2. 添加具有降序值的字段到数据
对于后一种方法,通常具有反转时间戳。
-1 * new Date().getTime();

另一答案添加一个列,即值为(-1*System.currentTimeMillis())的时间戳,并根据您的要求使用orderByChild("timestamp").limitToFirst(15)orderByChild("timestamp").limitToLast(15)获取数据。以排序的方式获取数据是明智的,因为firebase没有降序规则。
另一答案如果您使用Recycler视图呈现该数据,我会发现一个很好的解决方案......
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);

另一答案我没有看到任何反转数据的选项。但One Brute的方法是获取数据。
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(); }

另一答案我通过扩展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)); }

}
另一答案@Monet_z_Polski方法,基于
@Override public T getItem(int position) { return super.getItem(getCount() - (position + 1)); }

对自动更新FirebaseRecyclerView有一个奇怪的影响(PopulateViewHolder不会在实时更改中触发)。因此,最好的选择是使用否定键来索引数据。
另一答案客户端排序很简单,不需要更多系统资源。每个数据快照都有previousChildkey字段。如果你想要desc排序,想象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); } } }

另一答案斯威夫特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 })

另一答案可以使用android.support.v7.util.SortedList对TIMESTAMP对子项进行排序
class post{ private Object time; public Object getTime() { return time; }public void setTime(Object time) { this.time = time; } ...//rest code}SortedList< post> data; data = https://www.songbingjia.com/android/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 coderef.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也可以与RecyclerView一起使用
另一答案如果您在Web上执行此操作,则可以在数组中推送值,然后以相反的顺序打印存储的值。
var a=[]; //declaring an array a. var num=snapshot.numChildren(); //storing number of children in var num. a.push(snapshot.val()); // pushing data in the array. if (a.length==num){ //checking if length of array is same as number of children. a.reverse(); //reversing the array elements. for(i=0; i< num; i++){ a[i].name; //this will sort the data in descending order. } }


    推荐阅读