はじめに

Firebaseで現在(2018年4月)β版で稼働しているCloudFireStore、既存のRealtimeDatabaseより強力で高性能らしいがコンソールで操作できることが少ない。
コンソールで手動で入力するかスクリプトを書いてアップロードするしか方法がない。
Realtimeatabaseのようにjsonからインポートするために2時間ほど四苦八苦したまとめ。
基本はこのサイトを参考にした。

環境について

MacOS High Sierra
Node v9.11.1

データ構造について

Firestoreは三段階のデータ構造を持っている。

  1. Collection - Documentを格納している
  2. Document - CollectionもしくはFieldを格納している
  3. Field - KeyとValueのペア

Collectionは中身のDocumentを全て削除しないと消えない

これを理解せずにCollectionを乱立させた結果、DBがぐちゃぐちゃになったので注意。

データ管理用のアカウントを作る

FirebaseコンソールからProjectOverviewの隣の設定 --> Users and Permission
--> Service Account --> Create Service Account

Service account name は data-transfer (なんでもいい)
Role は Project --> Editor
Furnish a new private key にチェック、Key type はJSON

アカウントを作ると管理用アカウントの鍵がダウンロードされる。
名前をservice-key.jsonに変えておく

用意

Firestoreデータ管理用のフォルダを作ると楽
firebase-adminをインストールする
node install firebase-admin

フォルダ内
- node_modules
- service-key.json
- data.json(インポートしたいデータ)
- json-to-firestore.js(後述)

JSONからアップロード

パターン1:複数のCollectionを作る場合。

data.json
{
    "CollectionName1": {
        "DocumentName1": {
            "key1": "value1"
        }
    }
}
json-to-firestore.js
const admin = require('./node_modules/firebase-admin');
const serviceAccount = require("./service-key.json");

const data = require("./data.json");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://<YOUR_DB>.firebaseio.com"
});

data && Object.keys(data).forEach(key => {
    const nestedContent = data[key];

    if (typeof nestedContent === "object") {
        Object.keys(nestedContent).forEach(docTitle => {
            admin.firestore()
                .collection(key)
                .doc(docTitle)
                .set(nestedContent[docTitle])
                .then((res) => {
                    console.log("Document successfully written!");
                })
                .catch((error) => {
                    console.error("Error writing document: ", error);
                });
        });
    }
});

パターン2:一つのCollectionを作る場合

data.json
{
    "DocumentName1": {
        "key1": "value1"
    }
}
json-to-firestore.js
const admin = require('./node_modules/firebase-admin');
const serviceAccount = require("./service-key.json");

const data = require("./data.json");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://<YOUR_DB>.firebaseio.com"
});

data && Object.keys(data).forEach(key => {
    const nestedContent = data[key];

    admin.firestore()
        .collection('<COLLECTION NAME>')
        .doc(key)
        .set(nestedContent)
        .then((res) => {
            console.log("Document successfully written!");
        })
        .catch((error) => {
            console.error("Error writing document: ", error);
        });
});

パターン3:深くネストされたJSONの場合

こちらに使えそうなコードがありました。
Node 8.0 以降が必要になります。
検証したら書きます。

終わりに

Firestoreはまだβ版ですがこれから使われることも増えると思います。
そのうちJSONのインポートもコンソールで出来るようになる(なればいいな)かもしれないのでそれまではこの方法を使いましょう。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.