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

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

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

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

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

【问题讨论】:

标签: ios timestamp 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() 监听器被调用了两次。监听器将被调用两次。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-03
        • 1970-01-01
        • 2017-09-19
        • 1970-01-01
        • 1970-01-01
        • 2019-02-07
        • 1970-01-01
        相关资源
        最近更新 更多