如何从 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)