知识就是力量,时间就是生命。这篇文章主要讲述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()
)。没有办法表明您希望项目按降序排列。有两种方法可以获得您想要的行为:
- 使用Firebase查询获取正确的数据,然后在客户端重新排序
- 添加具有降序值的字段到数据
-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.
}
}
推荐阅读
- 调用getText()不在Android应用程序中编译
- 来自Postman的回复显示200,但Android返回403
- Android Google登录失败com.google.android.gms.common.api.ApiException(12500)
- 无法找到com.android.tools.build:gradle:2.3.+的任何匹配项
- 在React App中使用或不使用PouchDB加载预构建的SQlite数据库的正确方法是什么
- upsert方法的Android sqlite语法错误
- 将用户输入编辑文本与SQLite数据库Android Java进行比较
- 在Android中使用SQLite获取RowID
- 锁定AppendAllText与TextWriter