NodejsでFirestoreにデータを入れる時(エンティティ)クラスをそのまま入れようとするとFirestoreからJavascript objectじゃないとだめ!と言われたのでその方法を書きます。
結果から言うとこれでできた
JSON.parse(JSON.stringify(class_instance));
絶対他にもいい方法はあると思います...
classインスタンスをFirestoreに入れようとすると以下のエラーが出ます
Error: Value for argument "data" is not a valid Firestore document. Couldn't serialize object of type "(クラス名)". Firestore doesn't support JavaScript objects with
custom prototypes (i.e. objects that were created via the "new" operator).
要するに「今入れようとしてるデータはJavaScript Objectじゃないから何のデータなのかよくわからんかったわ!」ってことです。
classは確かにJavaScript Objectじゃないので入れることはできません。ならばObject.create()
すればできるのでは?と考えました。
...が残念ながら何も出力されませんでした。Object.create()
がだめならnew Object()
でやってみようということで試してみたら出力できました。
※ これを書いているときに試した時new Object()
しなくともclass自体がobjectなので必要なかったです。
...がそれでもだめでした。そもそも私がjavascriptがどういうものかを理解してなかったからです。
本来であればJavascript Objectは{}
で始まりますがnew Object()
だとクラス名 {}
となるためだめでした。
悩みに悩んでJSON.stringify()
でJSON化してしまえばJavascript Objectとして利用できると考えました。
...がそれもうまくいきませんでした。おかしいなと思い色々調べていった結果とある事に気づきました。
そもそもJSON.stringify()
の返り値はObjectじゃなくてStringだったってこと
盲点でした。なんでstringifyという名前なのに今まで気づかなかったのか逆に不思議です。
StringということがわかったならもうJSON.parse()
してしまえば解決です。
この方法はあくまでエンティティとして保存してあるプロパティデータをFirestoreに入れる方法なので他の用途ではあまり使えないと思います。
例えば
class Test {
constructor () {
this.foo = "string";
this.bar = 0;
this.qux = () => console.log("qux");
}
static baz () {
console.log("baz");
}
}
const test = new Test();
console.log(JSON.parse(JSON.stringify(test)));
この場合quxとbazは取り除かれた状態で変換されます。Firestoreにはfunctionは保存できないので必要ないですがfunctionが必要な他の用途で使いたい場合はこのやり方は使えません。