LoginSignup
3
5

More than 3 years have passed since last update.

【Swift】Cloud FirestoreのドキュメントにcreatedAtとupdatedAtを登録する実装

Posted at

はじめに

createdAtとupdatedAtはRDBだと自動的に生成してくれますが、Cloud Firestoreでは基本的にはクライアントからデータを登録する必要があります。
しかし、クライアント側で生成した日付データは改竄可能なので、Firestoreに適切ではない日付が登録される可能性があります。
そこでFirestore側には、ドキュメントがFirestoreに登録された時点での日付を設定できる関数が用意されています。
今回はその関数を使って、createdAtとupdatedAtを実装したいと思います。

ドキュメントの定義

まずはcreatedAtとupdatedAtを付与するドキュメントを下記のように定義しました。

SampleData.swift
import Firebase

struct SampleData: Codable {
    internal let createdAt: Timestamp? = nil
    internal let updatedAt: Timestamp? = nil
}

このSampleDataをFirestoreに登録した時に、createdAtとupdatedAtに登録した日付が保存されていることがゴールとなります。

Firestoreに登録された日付をcreatedAtとupdatedAtに設定する

Firestoreに登録された日付を設定するにはFieldValue.serverTimestamp関数を使用します。
この関数をメンバに持たせておくことで、そのデータがFirestoreに保存されたタイミングで、日付を自動的に設定してくれるというものです。
具体的には下記のように実装します。

SampleData.swift
struct SampleData: Codable {
    internal let createdAt: Timestamp? = nil
    internal let updatedAt: Timestamp? = nil
    // ①
    enum CodingKeys: String, CodingKey {
        case createdAt
        case updatedAt
    }
}

extension SampleData {
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        // ②
        if self.createdAt == nil {
            try container.encode(FieldValue.serverTimestamp(), forKey: .createdAt)
        }
        // ③
        try container.encode(FieldValue.serverTimestamp(), forKey: .updatedAt)
    }
}

①では、SampleDataをEncode&Decodeする対象のメンバを指定しています。
②のcreatedAtでは、登録された日付を保持したいので、登録時のみ(つまり初期値nilの場合)設定するようにしています。
③のupdateAtでは、更新されるたびに日付を上書きしたいので常にFieldValue.serverTimestamp()を設定します。

SampleDataを新規で登録する際はcreatedAtとupdatedAt両方に日付データが保存され、更新時にはupdatedAtだけ更新されるようになります。
EntityをEncode&Decodeする実装はこちらの記事で解説しています。

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5