Firebase CLI プロジェクトの Google Cloud Functions へファイルをアップロードして、Google Cloud Storageへ保存するコードをTypeScriptで書く
1.環境整備
Firebase CLIプロジェクトの生成は、この辺。
Firebase CLI プロジェクトで、Functionsを有効にすると、functions ディレクトリが生成されるので、その中で、以下のnpmパッケージをインストールする。
- Google Cloud Storage
- Busboy : HTMLのFormを解析するNode.jsモジュール。@types/busboy はTypeScript用の型定義
cd functions npm install @google-cloud/storage --save npm install busboy --save npm install @types/busboy --save
2.Cloud Storageのバケットを定義
Firebase コンソールからStorage を選択、バケットを追加する。
3.Functionsのコード
- Cloud Function でHTTPマルチパートデータを送信する を参考に、TypeScriptでCloudStorageに書き込む
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();
import * as path from 'path';
import * as os from 'os';
import * as fs from 'fs';
import * as Busboy from 'busboy';
export const helloStorage = functions.https.onRequest((request, response) => {
if (request.method !== 'POST') {
response.status(405).end();
return;
}
const bucket = admin.storage().bucket("gs://Cloud Storage のバケットURL");
const busboy = new Busboy({headers: request.headers});
const tmpdir = os.tmpdir();
const fields: {[key:string]:string} = {};
const uploads: {[key:string]:string} = {};
busboy.on('field', (fieldname, val) => {
console.log(`Processed field ${fieldname}: ${val}.`);
fields[fieldname] = val;
});
const fileWrites: Array<Promise<any>> = [];
busboy.on('file', (fieldname, file, filename) => {
console.log(`Processed file ${filename}`);
const filepath = path.join(tmpdir, filename);
console.log(`Filepath ${filepath}`);
uploads[fieldname] = filepath;
const writeStream = fs.createWriteStream(filepath);
file.pipe(writeStream);
const promise = new Promise((resolve, reject) => {
file.on('end', () => {
writeStream.end();
});
writeStream.on('finish', resolve);
writeStream.on('error', reject);
});
fileWrites.push(promise);
});
busboy.on('finish', async () => {
await Promise.all(fileWrites);
for (const file in uploads) {
const filepath = uploads[file];
console.log(`Finish filename:${filepath}`);
await bucket.upload(filepath)
.then(
res => console.log(`GCS res : ${res}`)
)
.catch(
() => console.log("GCS ERROR")
);
console.log(`UN LINK FILE : ${filepath}`);
fs.unlinkSync(filepath);
}
response.send();
});
busboy.on('error', async () => {
console.log("busboy on error");
});
busboy.end(request.rawBody);
});
4.Functionsデプロイ
firebase deploy --only functions
5.ファイルアップロードテスト用HTML
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="uft-8"> </head> <body> <form action="https://Cloud Functions の URL/helloStorage" method="POST" enctype="multipart/form-data"> <p><input type="text" name="txt_param1"></p> <p><input type="file" name="upload_file1"></p> <p><input type="file" name="upload_file2"></p> <p><input type="submit" value="Submit"></p> </form> </body> </html>
6.実行
ファイルアップロードテスト用HTMLを起動、適当にファイルをアップロード
6.Google Cloud Platform のログビューアで確認
- 上記ソースで、console.log に書き出した、form パラメーターやテンポラリのファイル格納パスなどが想定通り出力された!
7.Cloud Storageにアップロードされた
次は、Cloud Vision APIにつなぐぞ。