Skip to content

Instantly share code, notes, and snippets.

@slofp
Created April 6, 2020 02:49
Show Gist options
  • Save slofp/1570bc8c0da9d97e5151f9bc08893081 to your computer and use it in GitHub Desktop.
Save slofp/1570bc8c0da9d97e5151f9bc08893081 to your computer and use it in GitHub Desktop.
classプロパティをFirestoreに入れたい!

classプロパティをFirestoreに入れたい!

NodejsでFirestoreにデータを入れる時(エンティティ)クラスをそのまま入れようとするとFirestoreからJavascript objectじゃないとだめ!と言われたのでその方法を書きます。

tl;dr

結果から言うとこれでできた

JSON.parse(JSON.stringify(class_instance));

絶対他にもいい方法はあると思います...

classのデータをどうやってFirestoreにいれよう?

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じゃないから何のデータなのかよくわからんかったわ!」ってことです。

1回目の試行: new Object()

classは確かにJavaScript Objectじゃないので入れることはできません。ならばObject.create()すればできるのでは?と考えました。 ...が残念ながら何も出力されませんでした。Object.create()がだめならnew Object()でやってみようということで試してみたら出力できました。

※ これを書いているときに試した時new Object()しなくともclass自体がobjectなので必要なかったです。

...がそれでもだめでした。そもそも私がjavascriptがどういうものかを理解してなかったからです。

本来であればJavascript Objectは{}で始まりますがnew Object()だとクラス名 {}となるためだめでした。

2回目の試行: JSON.stringify()

悩みに悩んでJSON.stringify()でJSON化してしまえばJavascript Objectとして利用できると考えました。 ...がそれもうまくいきませんでした。おかしいなと思い色々調べていった結果とある事に気づきました。

そもそもJSON.stringify()の返り値はObjectじゃなくてStringだったってこと

盲点でした。なんでstringifyという名前なのに今まで気づかなかったのか逆に不思議です。

3回目の試行: JSON.parse()

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が必要な他の用途で使いたい場合はこのやり方は使えません。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment