iOS
Swift
Firebase
Firestore
CloudFirestore

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

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

ServerTimestamp利用してますか?

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

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

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

これは、実験して見たサンプルです。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でも中の人に直接改善をお願いしていました。FirebaseのIssueとしても改善を呼びかけていました。
真摯に話を聞いて頂き、このように対応して頂いたのは本当に嬉しいです。

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

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

大きな変更点

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

/**
 * 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 値が決定するまでは前回の値が利用されます。

詳細は、ドキュメントで確認してください。

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