#できたこと
FirebaseのFirestoreを使っており、その更新作業を自動でできないか考えた。
Cloud StorageへのExcelアップロードをトリガーにCloud functionsを発火させ、Firestoreの更新が行われる仕組みづくりをしてみた。
意外と面倒だったのでメモメモ。
#コード
##実装全体
これをcloud functionsへデプロイ。
今回はNode.jsで記述。
//もろもろ
const cors = require('cors')({ origin: true });
const path = require('path');
const os = require('os');
const functions = require('firebase-functions')
//必要な情報
const keyFilename = "path/to/keyfile";
const projectId = "YOUR PROJECT ID";
//おまじない
const admin = require('firebase-admin')
admin.initializeApp(functions.config().firebase)
const gcs = require('@google-cloud/storage')({
projectId,
keyFilename
});
const bucket = gcs.bucket("YOUR BUCKET NAME");
//ここからが処理内容
exports.helloWORLD = (event, context) => {
//トリガーの内容はeventかcontextに入る
const gcsEvent = event;
const file_name = event.name
const tempFilePath = path.join(os.tmpdir(), file_name);
//gcs bucketからexcelをダウンロードする
//一時ファイルとしてfunctionsのローカル環境にダウンロードする
bucket
.file(file_name)
.download({
destination: tempFilePath
})
.catch(err => {
console.error('テンプレファイルダウンロードエラー:', err);
})
.then(() => {
//Excelの処理に必要なおまじない
let XLSX = require('xlsx')
let workbook = XLSX.readFile(tempFilePath)
//Excelの取ってきたいデータを参照
let sheet_name_list = workbook.SheetNames
let Sheet1 = workbook.Sheets[sheet_name_list[0]] // 1つめのシートデータを取得します
let sheet_info_json = XLSX.utils.sheet_to_json( Sheet1 ) // データをJSONパースします
//Firestoreにぶち込むための入れ物
let input_info = []
//各行のデータが一つずつclに入る。cl[列のタイトル]でデータが取り出せる
for (let cl of sheet_info_json){
input_info.push({"name":cl["品目"],"price":cl["値段"]})
}
// データベースの参照を作成
var fireStore = admin.firestore()
var citiesRef = fireStore.collection(YOUR COLLECTION NAME);
citiesRef.doc(YOUR DOCUMENT NAME).set({
data: input_info}
)
}) //then
}; //export
package.jsonの中身はこちら。
{
"name": "sample-cloud-storage",
"version": "0.0.1",
"dependencies": {
"@google-cloud/storage": "^1.6.0",
"cors":"^2.8.5",
"firebase": "^7.14.2",
"firebase-admin": "^8.6.0",
"firebase-functions": "^3.3.0",
"os":"^0.1.1",
"path":"^0.12.7",
"xlsx":"^0.16.9"
}
}
##実装こまごま
###GCS⇔cloud functionsの連携
こちらの記事を無茶苦茶参考にしました。
cloud storageにあるExcelを一旦ローカルに保存するという発想もこちらのものです。
GCSのファイナライズをトリガーにしていますが、eventやcontextの中身についてはFirebaseの公式サイトをご覧ください。
pythonで実装された人の記事はこちらやこちらからご覧ください。
個人的に「バケット名ってどこからどこまでやねん」となりましたが、gs://ultra-soul.appspot.comの場合、ultra-soul.appspot.comがバケット名です。
公式ドキュメントに書かれていたけど全然気づかなかった。。。
###cloud functions内のExcelの処理
Excelをいじれるモジュールはいろいろあるみたいで、今回はxlsxを利用しました。
幾つか調べものをした結果をここにも載せておきます。
・exceljsモジュール
便利そうで実際ハンズオンしたけれど、今回の目的には少し使いにくかった。
npm公式サイトはこちらから
・xlsxモジュール
今回はこちらを利用!参考記事はこちらから
ちなみにcsvの場合はこちらの記事が便利そう。
csvばかりでExcelをインポートするための情報が少なすぎて苦労しました。。。
###cloud functions⇔Firebase firestoreの連携
こちらの記事を無茶苦茶参考にしました。
collectionとかdocumentとかの設計についてはこちらの記事を参考にしました。
collectionは検索するのが難しく、documentは検索がサクッと行えるのが私個人的な実感。
APIドキュメントはこちらから
###Firebase CLIを使ったデプロイ
これは素直に公式ドキュメントを参考にしました。
CLI上でプロジェクトの切り替えの方法はこちらから
使い慣れると便利!!
#最後に
pythonでも実装してみたいなぁ