#はじめに
Firebaseで現在(2018年4月)β版で稼働しているCloudFireStore、既存のRealtimeDatabaseより強力で高性能らしいがコンソールで操作できることが少ない。
コンソールで手動で入力するかスクリプトを書いてアップロードするしか方法がない。
Realtimeatabaseのようにjsonからインポートするために2時間ほど四苦八苦したまとめ。
基本はこのサイトを参考にした。
####環境について
MacOS High Sierra
Node v9.11.1
#データ構造について
Firestoreは三段階のデータ構造を持っている。
- Collection - Documentを格納している
- Document - CollectionもしくはFieldを格納している
- 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を作る場合。
{
"CollectionName1": {
"DocumentName1": {
"key1": "value1"
}
}
}
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を作る場合
{
"DocumentName1": {
"key1": "value1"
}
}
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のインポートもコンソールで出来るようになる(なればいいな)かもしれないのでそれまではこの方法を使いましょう。