以降序显示帖子显示帖子
我正在尝试测试Firebase,以允许用户使用push
发表评论。 我想用下面的方式显示我检索的数据;
fbl.child('sell').limit(20).on("value", function(fbdata) { // handle data display here }
问题是数据是按照最旧到最新的顺序返回的 – 我想要以相反的顺序。 Firebase能做到这一点吗?
自从写了这个答案之后,Firebase添加了一项功能,允许任何孩子或按价值排序。 所以现在有四种方法来定购数据:按键,按价值,按优先级或按任何有名儿的价值。 看到这个博客文章介绍了新的订购能力 。
基本的方法仍然是一样的:
1.添加一个带有倒置时间戳的子属性,然后对其进行排序。
2.按升序阅读孩子,然后在客户端反转。
Firebase支持以两种方式检索集合的子节点:
- 按名字
- 优先
你现在得到的是名字,这恰好是按时间顺序排列的。 这不是偶然的巧合:当你push
一个项目push
入一个集合时,会生成这个名字以确保孩子们以这种方式排列。 引用Firebase文档进行push
:
push()生成的唯一名称前面加上客户端生成的时间戳,以便生成的列表按时间顺序排序。
有关订购数据的Firebase指南对此有话说:
数据如何排序
默认情况下,Firebase节点上的子项按名称按字典顺序排序。 使用
push()
可以生成自然按时间顺序排序的子名称,但许多应用程序都要求以其他方式排序数据。 借助Firebase,开发人员可以通过为每个项目指定自定义优先级来指定列表中项目的排序。
获得所需行为的最简单方法是在添加项目时还指定始终递减的优先级:
var ref = new Firebase('https://your.firebaseio.com/sell'); var item = ref.push(); item.setWithPriority(yourObject, 0 - Date.now());
更新
你还必须以不同的方式检索孩子:
fbl.child('sell').startAt().limit(20).on('child_added', function(fbdata) { console.log(fbdata.exportVal()); })
在我的测试中,使用on('child_added'
确保最后添加的几个孩子按照时间倒序返回。另一方面,使用on('value'
,按照他们的名字顺序返回。
请务必阅读“阅读有序数据”部分 ,该部分解释了使用child_*
事件检索(排序)的孩子。
一个斌来演示这个: http : //jsbin.com/nonawe/3/watch?js,console
由于limitLast()
2.0.x可以使用limitLast()
来实现:
fbl.child('sell').orderByValue().limitLast(20).on("value", function(fbdataSnapshot) { // fbdataSnapshot is returned in the ascending order // you will still need to order these 20 items in // in a descending order }
以下是公告的链接: 更多查询Firebase中的功能
为了增加弗兰克的答案,也可以通过简单地使用endAt().limit(x)
来获得最近的记录 – 即使你没有打算使用优先级来排序它们endAt().limit(x)
var fb = new Firebase(URL); // listen for all changes and update fb.endAt().limit(100).on('value', update); // print the output of our array function update(snap) { var list = []; snap.forEach(function(ss) { var data = ss.val(); data['.priority'] = ss.getPriority(); data['.name'] = ss.name(); list.unshift(data); }); // print/process the results... }
请注意,这甚至可能高达一千个记录(假设有效载荷很小)。 对于更强大的用法,弗兰克的答案是权威的,更具可扩展性。
这种蛮力也可以通过监视child_added
/ child_removed
/ child_moved
事件代替value
来优化,以处理更大的数据或更多的记录,并使用去抖动批量应用DOM更新而不是单独应用。
自然,DOM更新无论采取什么方法,都是一个问题,一旦进入了数百个元素,那么去抖动方法(或React.js解决方案,实质上是一个超级反弹)是一个很好的工具。
我有一个日期变量(长),并希望保持在列表上的最新项目。 所以我做的是:
- 添加一个新的长字段'dateInverse'
- 添加一个名为“getDateInverse”的新方法,它只返回:Long.MAX_VALUE – date;
- 创建我的查询:.orderByChild(“dateInverse”)
- 普雷斯托! :p
你正在搜索limitTolast(Int x)。这会给你数据库中最后的“x”更高的元素(它们是按升序排列),但是它们是“x”更高的元素
如果你有你的数据库{10,300,150,240,2,24,220}
这个方法:
myFirebaseRef.orderByChild("highScore").limitToLast(4)
会回顾你:{150,220,240,300}
Firebase:如何以相反的顺序显示一个项目的线程,每个请求的限制和一个“加载更多”按钮的指标。
- 这将得到列表的最后10个项目
FBRef.child(“childName”).limitToLast(loadMoreLimit)//例如loadMoreLimit = 10
-
这将得到最后10个项目。 抓取列表中最后一个记录的id,并保存加载更多的功能。 接下来,将对象集合转换为数组,并执行list.reverse()。
-
LOAD MORE功能:下一次调用将做两件事,它将根据第一个请求中的参考ID获得下一个列表项序列,并在需要显示“加载更多”按钮时为您提供一个指示器。
this.FBRef .child(“childName”).endAt(null,lastThreadId)//从上一步获取.limitToLast(loadMoreLimit + 2)
-
你将需要去掉这个对象集合的第一个和最后一个项目。 第一个项目是获得这个列表的参考。 最后一项是显示更多按钮的指示器。
-
我有一堆其他的逻辑,将保持一切清洁。 您将需要添加此代码仅用于加载更多的功能。
list = snapObjectAsArray; // The list is an array from snapObject lastItemId = key; // get the first key of the list if (list.length < loadMoreLimit+1) { lastItemId = false; } if (list.length > loadMoreLimit+1) { list.pop(); } if (list.length > loadMoreLimit) { list.shift(); } // Return the list.reverse() and lastItemId // If lastItemId is an ID, it will be used for the next reference and a flag to show the "load more" button. }
我正在使用ReactFire轻松实现Firebase集成。
基本上,它可以帮助我将数据存储到组件状态,作为一个array
。 然后,我必须使用的是reverse()
函数( 阅读更多 )
这是我如何实现这一点:
import React, { Component, PropTypes } from 'react'; import ReactMixin from 'react-mixin'; import ReactFireMixin from 'reactfire'; import Firebase from '../../../utils/firebaseUtils'; // Firebase.initializeApp(config); @ReactMixin.decorate(ReactFireMixin) export default class Add extends Component { constructor(args) { super(args); this.state = { articles: [] }; } componentWillMount() { let ref = Firebase.database().ref('articles').orderByChild('insertDate').limitToLast(10); this.bindAsArray(ref, 'articles'); // bind retrieved data to this.state.articles } render() { return ( <div> { this.state.articles.reverse().map(function(article) { return <div>{article.title}</div> }) } </div> ); } }
真的没有办法,但似乎我们有回收查看我们可以有这个
query=mCommentsReference.orderByChild("date_added"); query.keepSynced(true); // Initialize Views mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView); mManager = new LinearLayoutManager(getContext()); // mManager.setReverseLayout(false); mManager.setReverseLayout(true); mManager.setStackFromEnd(true); mRecyclerView.setHasFixedSize(true); mRecyclerView.setLayoutManager(mManager);
在Android中,有一种方法可以通过适配器实际上反转Arraylist对象中的数据。 在我的情况下,我不能使用布局管理器以降序反转结果,因为我正在使用水平的Recyclerview来显示数据。 将以下参数设置为recyclerview搞乱了我的UI体验:
llManager.setReverseLayout(true); llManager.setStackFromEnd(true);
我发现这个唯一的工作方式是通过RecyclerView适配器的BindViewHolder方法:
@Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { final SuperPost superPost = superList.get(getItemCount() - position - 1); }
希望这个答案能够帮助那些在Firebase中为这个问题苦苦挣扎的所有开发者。
类似于Spoetnic的回答,但在JavaScript中。 我添加了一个新的“invert_time”字段,索引该字段,然后使用orderByChild()&limitedToLast()。
反转时间字段的值:
var invert_time = Number.MAX_SAFE_INTEGER - Date.now();
我还在database.rules.json文件的字段中添加了一个新的索引 :
".indexOn": ["invert_time"]
然后在ref()中使用: .orderByChild("invert_time").limitToLast(10)
有一个更好的办法。 您应该通过负面的服务器时间戳进行排序。 如何得到负面的服务器时间戳甚至离线? 有一个隐藏的领域,这有助于。 来自文档的相关片段:
var offsetRef = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/.info/serverTimeOffset"); offsetRef.on("value", function(snap) { var offset = snap.val(); var estimatedServerTimeMs = new Date().getTime() + offset; });
我做了这个前置。
query.orderByChild('sell').limitToLast(4).on("value", function(snapshot){ snapshot.forEach(function (childSnapshot) { // PREPEND }); });
有人指出有两种方法可以做到这一点:
- 操作数据客户端
- 进行查询,将数据排序
我发现最简单的方法是使用选项1,但是通过LinkedList
。 我只是将每个对象追加到堆栈的前面。 它足够灵活,仍然允许列表在ListView
或RecyclerView
。 这样,即使它们按照最旧到最新顺序排列,仍然可以查看或检索最新到最旧的。
您可以添加一个名为orderColumn的列,您可以节省时间
Long refrenceTime = "large future time"; Long currentTime = "currentTime"; Long order = refrenceTime - currentTime;
现在在名为orderColumn的列中保存Long order,当您以orderBy(orderColumn)方式检索数据时,您将获得所需的内容。
只需在数组上使用reverse()
,假设你将值存储到一个数组items[]
然后做一个this.items.reverse()
ref.subscribe(snapshots => { this.loading.dismiss(); this.items = []; snapshots.forEach(snapshot => { this.items.push(snapshot); }); **this.items.reverse();** },