💭
Cloud StoregeにCSVファイルを置いたら、 Cloud Function経由でFirestoreにデータを入れる
はじめに
- Cloud Storageにアップした大きめのCSVファイルを、Cloud FunctionでFirestoreにインポートする方法をまとめました。
- 覚書程度に残してありますので、汚いのはご了承ください😓(要望があれば綺麗にしようかと)
環境
- Cloud Functions(第二世代)
- Cloud Storage
- Node.js
概要
- ユーザーがCSVファイルをアップロードしたら、Cloud Function経由でFirestoreにデータを入れる
const functions = require('@google-cloud/functions-framework')
const admin = require('firebase-admin')
const { parse } = require('csv-parse')
admin.initializeApp()
functions.cloudEvent('importCsvToFirestore', async (cloudEvent) => {
const db = admin.firestore()
// cloudEventからバケット名とファイル名を取得
const file = cloudEvent.data
console.log(`Bucket: ${file.bucket}, File: ${file.name}`)
const bucket = admin.storage().bucket(file.bucket)
const remoteFile = bucket.file(file.name)
const parser = parse({
columns: true,
skip_empty_lines: true,
})
// ファイルを読み込む
remoteFile
.createReadStream()
.pipe(parser)
.on('readable', async () => {
// バッファに読み込み可能なデータが溜まったら、バッチに書き込む
// 一回の Cloud Function の実行で、何度か実行されることに注意
let batch = db.batch()
let batchCount = 0 // バッチ内の書き込み回数
let record
while ((record = parser.read())) {
// 1行ずつ読み込み
const ref = db.doc(`path/to/doc`)
batch.set(ref, {
...record,
userId: Number(record.userId), // 数値型で保存したい場合は、Number()でラップしないと文字列に
}) // 1行ずつFirestoreに書き込み
batchCount++
// バッチ書き込みの上限は500件
if (batchCount >= 495) {
// バッチ書き込みの上限
await batch.commit()
batch = db.batch()
batchCount = 0
}
}
if (batchCount > 0) {
await batch.commit()
}
})
.on('error', (err) => {
console.error('CSVパースエラー:', err)
})
.on('end', async () => {
console.log('CSVファイルの処理が完了しました。')
})
})
Discussion