如何从 Firebase 的 iOS API 获取服务器时间戳?

Posted

技术标签:

【中文标题】如何从 Firebase 的 iOS API 获取服务器时间戳?【英文标题】:How do I get a server timestamp from Firebase's iOS API? 【发布时间】:2014-10-21 14:13:18 【问题描述】:

我有一个使用 Firebase 的 ios 应用程序,目前有一些字典的键是 NSDate 对象。这样做的一个明显问题是 NSDate 从设备的系统时间中提取,这不是通用的。

这样,使用 Firebase 的 iOS API 获取服务器时间戳(类似于 Web API 的 Firebase.ServerValue.TIMESTAMP)以便我可以按时间顺序对字典键进行排序的最佳方法是什么?

我也知道 childByAutoID 生成的 ID 的时间顺序,但我无法找出在代码中对这些 ID 进行排序的正确方法。虽然它们可能会按时间顺序返回,但只要在它们上调用 allKeys 之类的东西,顺序就会消失。

任何有关此问题的帮助将不胜感激!

【问题讨论】:

找到了这个小工具 - github.com/freak4pc/NSDate-ServerDate - 但如果 Firebase 提供了一些解决方案,我仍然很高兴。 【参考方案1】:

更新:在 Firebase 3.0 + Swift 中,您可以使用 FIRServerValue.timestamp()。在 Objective-C 中,这是[FIRServerValue timestamp]

在 Swift 中,您现在可以在 Firebase 2.0.3+(3.0 之前)中使用 FirebaseServerValue.timestamp()

Firebase.ServerValue.TIMESTAMP 在 iOS 中的等价物是 kFirebaseServerValueTimestamp。目前,这只适用于 Objective-C 而不是 Swift。

在 Swift 中,您可以使用

创建自己的全局时间戳
let kFirebaseServerValueTimestamp = [".sv":"timestamp"]

然后你就可以用同样的方式使用kFirebaseServerValueTimestamp了。

但你只能将它用作节点的值或优先级。您将无法将其设置为密钥名称(尽管我不相信您也可以在 Web API 中)。

通常,在字典 does not guarantee order. 上调用 allKeys 但如果您在节点上使用 childByAutoID,则可以通过按字典顺序对 allKeys 返回的 NSArray 进行排序来恢复正确的顺序。这样的事情会起作用:

[ref observeEventType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) 
    NSDictionary *value = snapshot.value;
    NSLog(@"Unsorted allKeys: %@", value.allKeys);
    NSArray *sortedAllKeys = [value.allKeys sortedArrayUsingSelector:@selector(compare:)];
    NSLog(@"Sorted allKeys: %@", sortedArray);
];

这类似于对NSArray alphabetically 进行排序,但在对自动生成的 ID 进行排序时,您确实想要本地化或不区分大小写的排序,因此您使用compare: 而不是localizedCaseInsensitiveCompare:

【讨论】:

【参考方案2】:

警告:似乎时间戳是添加之后您的对象在 Firebase 中持久化。这意味着如果您在对象被持久化的位置设置了 .Value 事件监听器,它将被触发 TWICE。一次用于存储在该位置的初始对象,再次用于添加时间戳。为这个问题苦苦挣扎了好几天:(

对于那些不知道为什么他们的事件监听器会触发两次/多次的人来说,这是有用的信息!

【讨论】:

【参考方案3】:

从 Firebase 4.0 开始,您可以使用 ServerValue.timestamp()

例如:

    let ref = Database.database().reference().child("userExample")
    let values = ["fullName": "Joe Bloggs", "timestamp": ServerValue.timestamp()] as [String : Any]

    ref.updateChildValues(values)  (err, ref) in

        if let err = err 
            print("failed to upload user data", err)
            return
        

    

【讨论】:

这很好,但是有办法直接从服务器检索时间戳值以在 updateChildalues 完成块中使用【参考方案4】:

您可以使用 FIRServerValue.timestamp() 获取时间戳。

但是,由于 FIRServerValue.timestamp() 监听器被调用了两次。监听器将被调用两次。

【讨论】:

以上是关于如何从 Firebase 的 iOS API 获取服务器时间戳?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:如何从谷歌登录firebase获取生日? (安卓和iOS)

在ios中上传后如何从firebase获取缩略图?

如何按文档 ID 从 Firebase Firestore 获取数据 - iOS?

如何向 ios 应用程序发送 Firebase 推送通知

如何从python中的firebase获取事件数据?

如何从Swift中的Cloud FireStore Firebase访问特定字段