对于我正在开发的iOS应用,我需要按降序获取消息,即最新消息排在第一位,然后是第二最新消息,依此类推。
从其他SO答案和研究来看,看来我的情况最好的方法是创建一个否定的时间戳,然后将其保留到数据库中作为消息的额外属性。
然后,我将使用queryOrderedByChild('negativeTimestamp')来获取中的消息,然后使用observeSingleEventchildAdded观察器来处理在进行初始调用后发送的消息。
queryOrderedByChild('negativeTimestamp')
observeSingleEvent
在firebase 文档中,它说我可以从此代码段 firebase.database.ServerValue.TIMESTAMP中* 获取服务器时间戳值。 *
如何为Swift 3编写此代码?
首先,请参阅评论中的链接答案。该答案取决于客户端生成的时间戳记,该时间戳记为负数并写入Firebase。
如果您想让Firebase生成时间戳,也可以使用这种小巧的Firebase结构和代码来完成。
首先,让我们看一下结构
root parent_node -Y8j8a8jsjd0adas time_stamp: -1492030228007 timestamp: 1492030228007
接下来,创建并使用该结构的一些代码:
定义一个可在我们的类中使用的变量,该变量引用Firebase时间戳
let kFirebaseServerValueTimestamp = [".sv":"timestamp"]
和一个将观察者添加到时间戳节点的函数:
func attachObserver() { let timestampRef = self.ref.child("timestamp") let parentNodeRef = self.ref.child("parent_node") var count = 0 timestampRef.observe(.value, with: { snapshot in if snapshot.exists() { count += 1 if count > 1 { let ts = snapshot.value as! Int let neg_ts = -ts let childNodeRef = parentNodeRef.childByAutoId() let childRef = childNodeRef.child("time_stamp") childRef.setValue(neg_ts) count = 0 } } })
还有一个写入时间戳的函数,因此导致观察者触发,该事件根据Firebase时间戳在parent_node内创建子节点
func doTimestamp() { let timestampRef = self.ref.child("timestamp") timestampRef.setValue(kFirebaseServerValueTimestamp) }
这是总结。
在attachObserver函数中,我们将观察者附加到时间戳节点-该节点可能存在或可能不存在,但如果不存在,将创建该节点- 继续阅读。每当时间戳节点中发生事件时,都会调用闭包中的代码。
调用doTimestamp函数时,它将创建时间戳并将其写入timestamp节点,然后触发我们附加在attachObserver中的观察者。
观察闭包中的代码执行以下操作:
确保快照中包含某些内容,如果包含,则增加一个计数器(稍等一下)。如果计数器大于1,则从快照获取时间戳作为整数。然后,创建它的底片,并将其作为parent_node的子代写回到Firebase。
无论何时您想使用Firebase生成的时间戳为子节点添加时间戳,但反向加载/排序的值为负,这将如何应用-这就是OP问题。
这里的陷阱是,当这种情况发生时
timestampRef.setValue(kFirebaseServerValueTimestamp)
它实际上向节点写入两次,这将导致更近的代码被调用两次。
也许Firebaser可以解释这一点,但是我们需要忽略第一个事件并捕获第二个事件,这是实际的时间戳。
因此,第一个事件将使观察者更接近触发点,使count = 1,由于if语句而将其忽略。
然后触发第二个事件,其中包含实际时间戳记,这就是我们用来使否定并写到Firebase的原因。
希望这对OP和评论者有所帮助。