CloudFirestoreのServerTimestampがより使いやすくなりました。

# CloudFirestoreのServerTimestampがより使いやすくなりました。

## ServerTimestamp利用してますか？

FirestoreのServerTimestampは、時間軸を全てサーバーに預けてしまうことによってモバイルの個体差によるずれを解消する機能です。

https://firebase.google.com/docs/reference/js/firebase.firestore.FieldValue

## 今まではサーバーで値が決定するまでnullだった。

これは、実験して見たサンプルです。Swiftですがなんとなくご覧下さい。

```swift
do {
    let db = Firestore.firestore().collection("test1").document("id")

    // ServerTimestampをセット
    db.setData(["test": FieldValue.serverTimestamp(), "key": "hoge"]) { (error) in

        // 一度Documentを取得する
        db.getDocument(completion: { (snapshot, error) in

            // ServerTimestampを確認
            print("TEST 0", snapshot?.data()["test"])

            // 何回かServerTimestampを更新
            (0..<5).forEach({ index in
                let batch = db.firestore.batch()
                batch.updateData(["test": FieldValue.serverTimestamp(), "key": "\(index)"], forDocument: db)
                batch.commit(completion: { _ in
                })
            })

            // 更新中に並列でServerTimestampを確認
            db.getDocument(completion: { (snapshot, error) in
                print("TEST 1", snapshot?.data()["test"])
            })

            // 数秒待ってServerTimestampを確認
            DispatchQueue.main.asyncAfter(deadline: .now() + 4, execute: {
                db.getDocument(completion: { (snapshot, error) in
                    print("TEST 2", snapshot?.data()["test"])
                })
            })
        })
    }
}
```

**結果**

```
TEST 0 Optional(2017-10-11 05:01:03 +0000)  // Snapshot取得直後
TEST 1 Optional(<null>)                     // データ更新中
TEST 2 Optional(2017-10-11 05:01:05 +0000)  // 数秒後
```

この挙動は、去年[FirebaseDevSummit](https://firebase.google.com/dev-summit-17/?hl=ja)でも中の人に直接改善をお願いしていました。Firebaseの[Issue](https://github.com/firebase/firebase-ios-sdk/issues/364#event-1444296736)としても改善を呼びかけていました。
真摯に話を聞いて頂き、このように対応して頂いたのは本当に嬉しいです。

さらに詳しい使い方については、サンプルがありますのでこちらでご確認ください。

https://github.com/firebase/snippets-ios/commit/6fb2d2e8713914cdae7b3719d468cfb2d9992bd3#diff-ac81ab115caf45e3d791eff7331d00bfR399

## 大きな変更点

`serverTimestampBehavior`が追加され、3つの取り扱い方法が提供されるようになりました。

```swift
/**
 * Controls the return value for server timestamps that have not yet been set to
 * their final value.
 */
typedef NS_ENUM(NSInteger, FIRServerTimestampBehavior) {
  /**
   * Return `NSNull` for `FieldValue.serverTimestamp()` fields that have not yet
   * been set to their final value.
   */
  FIRServerTimestampBehaviorNone,

  /**
   * Return a local estimates for `FieldValue.serverTimestamp()`
   * fields that have not yet been set to their final value. This estimate will
   * likely differ from the final value and may cause these pending values to
   * change once the server result becomes available.
   */
  FIRServerTimestampBehaviorEstimate,

  /**
   * Return the previous value for `FieldValue.serverTimestamp()` fields that
   * have not yet been set to their final value.
   */
  FIRServerTimestampBehaviorPrevious
} NS_SWIFT_NAME(ServerTimestampBehavior);
```
| FIRServerTimestampBehavior | 説明 |
|---|---|
| FIRServerTimestampBehaviorNone | 今までと同じ、値が決定するまでnullが入ります。 |
| FIRServerTimestampBehaviorEstimate | おおよその見積もりをしてくれます。見積もり時間と最終的に決定した時間にはズレが生じる場合があります。 |
| FIRServerTimestampBehaviorPrevious | 値が決定するまでは前回の値が利用されます。 |

詳細は、[ドキュメント](https://firebase.google.com/docs/reference/ios/firebasefirestore/api/reference/Classes/FIRSnapshotOptions?hl=ja#/c:objc(cs)FIRSnapshotOptions(cm)serverTimestampBehavior:)で確認してください。

ますますFirestoreにより開発に精が出ますねぇ。それでは良いFirebaseライフを