首页 > 解决方案 > Firebase 是否始终保证按顺序添加事件?

问题描述

我正在开发基于 Firebase 实时数据库的 Messenger IOS 应用程序。我希望所有消息都根据时间戳进行排序。

有一个场景如下。

有3个客户。A、B 和 C。

1)

所有客户端都注册“figure-1”侦听器以接收来自其他人的消息。

<figure-1>

ref.queryOrdered(byChild: "timestamp").queryStarting(atValue: startTime).observe(.childAdded, with:
{
    ....
    // do work for the messages, print, save to storage, etc.
    ....

    // save startTime to storage for next open.     
    startTime = max(timeOfSnapshot, startTime)
    saveToStorage(startTime)
}

2)

Client A write  message 1 to server with ServerValue.timestamp().
Client B write  message 2 to server with ServerValue.timestamp().
Client C write  message 3 to server with ServerValue.timestamp().

他们在同一时刻发送了消息。

所有客户都有良好的速度 wifi。

所以,最后。服务器数据保存为“图 2”

<figure-2>

text : "Message 1",  timestamp : 100000001
text : "Message 2",  timestamp : 100000002
text : "Message 3",  timestamp : 100000003

作为我的听众的代码,我将消息保存在存储和下一个收听时间戳中,以防止下载重复的消息。

在这种情况下。

Firebase 是否总是保证按如下顺序触发回调?

Message 1
Message 2
Message 3

如果不能保证,我的策略是绝对错误的。

例如,某些客户端收到如下消息。

Message 3  // the highest timestamp.

// app crash or out of storage

Message 1
Message 2

客户端不再有机会获得消息 1、2。

我认为如果已经有一些节点,Firebase 可能会触发这些节点。因为,这是“queryOrdered”功能的作用。

但是,注册监听器之前没有节点,之后又添加了新节点。会发生什么?

我想 Firebase 可能会向客户端发送 3 个数据包。(无论消息到达多快,Firebase 都必须在它到达后立即发送出去。)

Packet1 for message1
Packet2 for message2
Packet3 for message3

ClientA fail to receive for packet 1,2 
ClientA success to receive for packet 3
Firebase re-send packet 1,2 again. 
ClientA success to receive for packet 1,2 

最终,所有数据都是一致的。但是排序已损坏。

Firebase 是否保证按顺序发生事件?

我已经多次搜索堆栈溢出和谷歌并阅读官方文档。但是,我找不到明确的答案。

为此,我几乎花了一周的时间。请给我一条建议。

标签: iosfirebasefirebase-realtime-database

解决方案


查询数据的返回顺序是一致的,由服务器决定。因此,所有客户端都可以保证以相同的顺序获得结果。

对于附加监听器后发送到数据库的新数据,所有远程客户端将按相同顺序接收它。但是,在数据到达数据库服务器之前,本地客户端会立即看到它的写操作事件。

在图 2 中,实际上非常简单:因为每个节点都有一个唯一的时间戳,并且它们将按照该时间戳的顺序返回。但即使它们具有相同的时间戳,它们也会以相同的顺序返回(首先是时间戳,然后是键)。


推荐阅读