Swift Firebase - 将估计的 ServerTimestamp 与可编码的自定义对象相结合
Posted
技术标签:
【中文标题】Swift Firebase - 将估计的 ServerTimestamp 与可编码的自定义对象相结合【英文标题】:Swift Firebase - Combining estimated ServerTimestamp with Codable Custom Objects 【发布时间】:2021-03-15 17:10:34 【问题描述】:我有一个消息应用程序,我的 Firebase Firestore 数据库中有一个 Chats
集合。我使用一个可编码的自定义对象来读取和写入对 firebase 的更改。
struct ChatFirebaseDO: Codable
@DocumentID var id: String?
... 100 other fields ...
var lastMessageDate: Date
当用户发送新消息时,我将 lastMessageDate
更新为 FieldValue.serverTimestamp()
我还有一个监听器正在监听更改,它会立即将任何更新返回给我(或者是对现有更新的新聊天)。但是,如果是我自己的用户创建了这个新聊天,它将返回给我,并带有 null
时间戳。
从文档中我看到这是故意行为。它建议我用估计的时间戳值替换空值(完美!)但是,我不知道如何将它与我的自定义对象结合起来。
要获得估计的时间戳,我需要这样做:diff.document.data(with: .estimate)
它返回一个字段字典。
但要让我的Codable
自定义对象起作用,我必须使用:let messageDO = try diff.document.data(as: ChatFirebaseDO.self)
它使用文档(不是数据字典)。
有没有一种方法可以 (1) 用估计的时间戳替换空值,但 (2) 仍然有一个文档对象可用于我的自定义对象转换。
也许我可以使用估计值进行全局设置,或者在单个侦听器请求中进行本地设置。或者也许它是一种使用数据字典中的自定义对象的方法,而不仅仅是来自FIRDocument
。
提前谢谢你!
【问题讨论】:
Firestore 不谈,是否要求您的结构为Codable
?
不是必需的,但它非常有用,并且在我的项目架构中是“家具的一部分”。仅仅因为 Firebase 的一个空时间戳而丢失它会很可惜。
【参考方案1】:
如果您没有将这些聊天编码用于磁盘存储,那么为什么它们甚至是Codable
是一个要问自己的问题。这种特殊的方法是为此目的而设计的,所以我认为您使用了错误的工具来完成这项工作 - 由于时间戳冲突,该工具也无法正常工作,我想这将在 Firestore 的未来更新中得到解决.
也就是说,时间戳(它们是令牌)仅在它们尚未到达服务器时返回 nil
,这意味着仅来自客户端生成的延迟补偿快照(或仅当登录用户发布时)。因此,您可以在值为nil
(即当前日期和时间)时提供您自己的估计,这不仅准确,而且当它具有实际值时,无论如何都会被后续快照覆盖。这不是一个令人愉快的解决方法,但它完全完成了令牌自己的估计所做的事情。
如果您不想放弃 Codable
,那么您可以放弃 Firestore 的时间戳,这是我亲自完成的。我不是令牌系统的粉丝,我已经用一个基本的 Unix 时间戳(一个整数)替换了它,这使得事情变得更加简单。我不必担心nil
次、延迟补偿返回或配置快照数据只是为了处理单个字段的值。如果我不得不猜测,我会想象 Firestore 最终将允许时间戳行为的全局设置,除了扩展 API 以允许 Codable
方法也考虑时间戳行为。它的 TLDR 是你想要的东西在 Firestore SDK 中还不存在,不幸的是,我会考虑在 Firestore-ios git repo 上将其作为功能请求。
【讨论】:
以上是关于Swift Firebase - 将估计的 ServerTimestamp 与可编码的自定义对象相结合的主要内容,如果未能解决你的问题,请参考以下文章
将 Firebase 数据放入数组以放入文本视图 (Swift)