LoginSignup
15

More than 5 years have passed since last update.

FirestoreへJSONをインポートする方法

Posted at

はじめに

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のインポートもコンソールで出来るようになる(なればいいな)かもしれないのでそれまではこの方法を使いましょう。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15