如何将Firebase设置为只观察新数据



我有一个观察函数,它显示添加到Firebase实时数据库的项目。

func observerMessages(completion: @escaping (FireBaseResponse, MessageDataModel) -> Void) {
let ref = Database.database().reference().child(FireBaseConstants.Database.messages).queryOrdered(byChild: FireBaseConstants.Database.timestamp).queryEnding(atValue: firstMessageTimestamp)
ref.observe(.childAdded) { (snapshot) in
if let dict = snapshot.value as? [String:Any] {
if let username = dict["username"] as? String,
let timestamp = dict["timestamp"] as? Int,
let text = dict["text"] as? String,
let senderId = dict["senderId"] as? String {
let message = MessageData(username: username, timestamp: timestamp, text: text, senderId: senderId, messageId: snapshot.key)
print("observeMessages")
completion(.success, message)
}
}
}
}

问题是,此函数会为数据库中已存在的所有项触发。因此,它检索该子级中的所有数据。我想让它检索数据,这些数据是在这个函数调用后添加的。

Firebase在服务器和客户端之间同步特定位置或特定查询的数据。没有内置的API只要求发送新数据。

有几种方法可以在API之上实现这一用途:

  1. 只将新数据存储在一个位置,并在客户端读取后将其删除。这是在Firebase上实现消息传递的常见方法:为每个客户端编写一个消息队列,并让客户端在处理数据时删除数据。

  2. 仅查询自客户端上次读取数据以来已写入的数据。这需要在每个子节点上都有一个createdAtupdatedAt时间戳属性,并将lastReadDataAt时间戳存储在客户端中。现在,当客户端连接时,它会运行一个按属性排序的查询,并传入上次同步的时间戳。有了这些参数,数据库将只返回自客户端上次读取以来创建/更新的数据。

  3. 只请求一个最近的项目。这意味着您可以按一些按时间顺序排列的键(例如childByAutoId生成的键(对数据进行排序,然后使用limitQuery(toLast:1)从数据库中只请求一个最近的子节点。这样,您只能获得一个最近的子节点。虽然这在某些情况下有效,但我几乎从未使用过它,因为当客户端失去连接时,可能会错过事件。

最新更新