手元の yml データを Firestore に入れる


例えば、手元の複数の yml ファイルを、Document として Firestore に入れたいとする。

yml

こういうのが data ディレクトリ以下に複数あるとする

foo.yml
- id: "hoge"
  name: "Hoge"
  age: "123"
- id: "fuga"
  name: "aaaa"
  age: "1"

script

こんな感じに書いて、 yarn run build && node lib/sample_yml_uploader.js みたいに叩く。

sample_yml_uploader.ts
import * as admin from 'firebase-admin'
import * as fs from 'fs'
import * as yaml from 'js-yaml'

// adminsdk_key の json を読み込む
const serviceAccount = require('./sample-adminsdk')

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://XXX.firebaseio.com",
})

// 特定のディレクトリ以下の yaml を全て読み込む
const loadResult = fs.readdirSync('./data').map(file => {
    const data = fs.readFileSync(`./data/${file}`, 'utf-8')
    return yaml.safeLoad(data);
}).filter(el => el != null);
const dataList =  Array.prototype.concat.apply([], loadResult) // flat な配列にする

// Firestore に Document を set/update する
dataList.forEach( data => {
    data['updatedAt'] = admin.firestore.FieldValue.serverTimestamp()
    const docRef = admin.firestore().collection('version/1/foo').doc(data['id'])
    admin.firestore().runTransaction( async tx  => {
         const doc = await tx.get(docRef)
         if (doc.exists) {
            doc.ref.update(data)
         } else {
            data['createdAt'] = admin.firestore.FieldValue.serverTimestamp()
            doc.ref.set(data)
         }
    }).catch(err => console.error('Error: ', err))
})

件数多いなら batch で書いた方がいい。