本稿では,Swift(Swift5.1)を使ってFirestoreから取得したデータをデコードする際に@DocumentIDアトリビュートを使えばidの付加が簡単になるという話を紹介します.
昨年秋からFirebaseFirestoreSwiftを使用することで公式にCodableが使えるようになりました.それについてはこちらの記事「公式の方法でFirestoreでCodable #firebase #firestore #codable」で紹介されています.
問題:普通にDecodeするとDocument idを取ってこれない
Decode先の型にidを持たせた場合,通常Firestore側のフィールドにidは含まれていないと思うのでうまく行きません.そこで,DocumentSnapshot.documentIdで後からidを指定する必要がありました.
struct HogeModel: Codable {
var id: String?
let hoge: Int
}
Firestore.firestore().document("collection/uuid001").getDocument { snapshot, error in
var data = try? snapshot?.data(as: HogeModel.self)
data.id = snapshot.documentId
}
@DocumentIDで自動的にidを付加する
Swift5.1で追加されたProperty Wrappersの機能を使って,FirebaseFirestoreSwiftで定義されているアトリビュート,@DocumentIDを使うことで,var idにDocumentIDを入れておいてほしいということを示すことができます.このため,FirebaseFirestoreSwiftをimportする必要があります.
import FirebaseFirestoreSwift
struct HogeModel: Codable {
@DocumentID var id: String?
let hoge: Int
}
Firestore.firestore().document("collection/uuid001").getDocument { snapshot, error in
var data = try? snapshot?.data(as: HogeModel.self)
//これだけでdataのidにdocumentIdが入っている
}
また,Encode時には@DocumentIDがついているプロパティは無視されるのでそのままEncodeしてFirestoreにアップロードすることが可能です.
Property Wrappers
以下,使用上知らなくてもいいですが気になるので書いておきます.
@DocumentIDというアトリビュートが使えるのはSwift5.1で追加されたProperty Wrappersを使ってFirebaseFirestoreSwiftで定義されているからです.
具体的には@propertyWrapperのアトリビュートがつけられたStructが定義されています.
@propertyWrapper
public struct DocumentID<Value: DocumentIDWrappable & Codable & Equatable>:
DocumentIDProtocol, Codable, Equatable {
}