🧯
firestoreへのデータ保存でundefinedな値を自動で取り除く
こんにちは、猫チーズです。
最近TypeScriptを学び始め、VSCodeのIntelliSenseの有り難みに気付いて、これと共に生きていこうと決意しました。
タイトルの解決方法は一番下に書いてあるので、経緯部分は読み飛ばしても問題無いです。
ユーザー名と年齢を保持するクラスがあったとします。
年齢はオプショナルです。
class User {
constructor(
public name: string,
public age?: number,
) {
this.name = name
this.age = age
}
// methods...
}
新しいユーザーを作ります
const taro = new User("Taro", 20) // タロウ 20歳
const tom = new User("Tom") // トム 年齢不詳
コンバーターを使ってデータをFirebaseに保存します。
import firebase from 'firebase'
const firestore = firebase.firestore()
// 保存用の形式
interface UserDoc {
name: string
age?: number
}
// User ←→ UserDoc 相互変換
const userConverter: firebase.firestore.FirestoreDataConverter<User> = {
toFirestore(user: User) {
return {
name: user.name,
age: user.age,
} as UserDoc
},
fromFirestore(snapshot, options): User {
const data = snapshot.data() as UserDoc
return new User(
data.name,
data.age,
)
}
}
firestore.doc("users/taro").withConverter(userConverter).set(taro)
firestore.doc("users/tom").withConverter(userConverter).set(tom)
ここで本題となる、tomの保存時にエラーが出てしまいます。
FirebaseError: Function DocumentReference.set() called with invalid data (via `toFirestore()`). Unsupported field value: undefined (found in field age in document users/tom)
new User("Tom")
をした時に年齢を設定していないので、tom.age
が undefined
となっていたからですね。
それで、JSONがundefinedを自動で存在しないものと扱ってくれるように、Firestoreでも同じことができないかなと調べたら出てきました。
「undefinedな時にエラーさせるのではなく無視させる(意訳)」
firebase.firestore.Settings
Firestoreでundefinedを無視させるオプションが今年の5月29日に追加されていたようです。割と最近。ありがたや。
ということで、firestoreであらゆる関数を実行する前に下の設定をすると、undefinedが無視されてくれます。
firebase.firestore().settings({
ignoreUndefinedProperties: true,
})
👏👏
Discussion