Cloud Storage 内のファイルやフォルダのアップロード、更新、削除に応じて、関数をトリガーできます。
このページの例は、画像ファイルが Cloud Storage にアップロードされたときにトリガーされるサンプル関数に基づいています。このサンプル関数は、イベント属性にアクセスする方法、ファイルを Cloud Functions インスタンスにダウンロードする方法、Cloud Storage イベントの処理に関するその他の基礎知識を示しています。
Cloud Storage の変更で関数をトリガーする
firebase-functions/v2/storage
サブパッケージを使用して、Cloud Storage イベントを処理する関数を作成します。関数のスコープを特定の Cloud Storage バケットにするか、デフォルトのバケットを使用するかに応じて、次のいずれかのパターンを使用します。
// scope handler to a specific bucket, using a string parameter
export archivedbucket = onObjectArchived("myBucket", (event) => {
//…
});
// scope handler to a specific bucket, using storage options parameter
export archivedopts = onObjectArchived({ bucket: "myBucket" }, (event) => {
//…
});
一方、このサムネイル生成関数は、プロジェクトのデフォルト バケットをスコープとします。
exports.generateThumbnail = onObjectFinalized({cpu: 2}, async (event) => { // ... });
関数のロケーションを設定する
Cloud Storage バケットのロケーションと関数のロケーションとの距離によっては、ネットワーク レイテンシが大幅に増加する可能性があります。ロケーションが一致しない場合、デプロイが失敗することもあります。このような状況を回避するには、次のいずれかの方法でバケットやトリガーのロケーションと一致するように関数のロケーションを指定します。
- 関数のロケーションがトリガーのロケーションと同じである
- 関数のロケーションがトリガーのロケーション内にある(トリガーのリージョンがデュアル / マルチ リージョンの場合)
- トリガーのリージョンが
us-central1
に設定されている場合、関数はどのロケーションにも配置できる
Cloud Storage イベントを処理する
Cloud Storage は、次のイベントをサポートしています。
Cloud Storage イベントに応答するハンドラは次のとおりです。
onObjectArchived
。バケットでオブジェクトのバージョニングが有効になっている場合にのみ送信されます。このイベントは、アーカイブ化の操作または同名オブジェクトのアップロードによる上書きが原因で、オブジェクトのライブ バージョンがアーカイブ バージョンになったことを表します。onObjectDeleted
。オブジェクトが完全に削除された場合に送信されます。バケットのライフサイクル構成で上書きまたは削除されたオブジェクトも対象になります。オブジェクトのバージョニングが有効になっているバケットでは、storage.objects.delete
メソッドによりオブジェクトがアーカイブされた場合も含めて、アーカイブの発生時にはこのイベントを送信しません(onArchive
参照)。onObjectFinalized
。バケットで新しいオブジェクト(または既存オブジェクトの新しい世代)が正常に作成された場合に送信されます。既存のオブジェクトのコピーまたは書き換えを行った場合にも送信されます。アップロードが失敗した場合、このイベントはトリガーされません。onMetadataUpdated
。既存オブジェクトのメタデータが変更された場合に送信されます。
Cloud Storage オブジェクトの属性にアクセスする
Cloud Functions は、更新されたファイルの size
や contentType
など、Cloud Storage オブジェクトのいくつかの属性を公開します。metageneration
属性は、オブジェクトのメタデータが変更されるたびに増分されます。新しいオブジェクトの場合、metageneration
の値は 1
です。
const fileBucket = event.data.bucket; // Storage bucket containing the file. const filePath = event.data.name; // File path in the bucket. const contentType = event.data.contentType; // File content type.
サムネイル生成サンプルでは、これらの属性のいくつかを使用して、関数が返される終了ケースを検出します。
// Exit if this is triggered on a file that is not an image. if (!contentType.startsWith("image/")) { return logger.log("This is not an image."); } // Exit if the image is already a thumbnail. const fileName = path.basename(filePath); if (fileName.startsWith("thumb_")) { return logger.log("Already a Thumbnail."); }
ファイルをダウンロード、変換、アップロードする
Cloud Storage からファイルをダウンロードする必要がない場合もありますが、Cloud Storage に保存されているファイルからサムネイル画像を生成するなどの込み入った作業を行う場合は、関数インスタンス(つまり、コードを実行する仮想マシン)にファイルをダウンロードする必要があります。
オブジェクトのダウンロードと Cloud Storage への再アップロードを簡単に行うには、npm install --save @google-cloud/storage
を使用して Google Cloud Storage パッケージをインストールし、インポートします。サンプル内のサムネイル処理タスクなどの外部プロセスを処理するために JavaScript Promise を使用するには、child-process-promise
もインポートします。
const {onObjectFinalized} = require("firebase-functions/v2/storage"); const {initializeApp} = require("firebase-admin/app"); const {getStorage} = require("firebase-admin/storage"); const logger = require("firebase-functions/logger"); const path = require("path"); // library for image resizing const sharp = require("sharp"); initializeApp();
gcs.bucket.file(filePath).download
を使用して、Cloud Functions インスタンスの一時ディレクトリにファイルをダウンロードします。この場所で、必要に応じてファイルを処理してから、Cloud Storage にアップロードできます。非同期タスクを実行するときは、コールバックで JavaScript Promise を返すようにしてください。
例: 画像変換
Cloud Functions を ImageMagick
などの画像処理プログラムと組み合わせて使用すると、グラフィカルな画像ファイルに対して操作を行うことができます。次に、アップロードした画像ファイルのサムネイル画像を作成する方法の例を示します。
// Download file into memory from bucket. const bucket = getStorage().bucket(fileBucket); const downloadResponse = await bucket.file(filePath).download(); const imageBuffer = downloadResponse[0]; logger.log("Image downloaded!"); // Generate a thumbnail using sharp. const thumbnailBuffer = await sharp(imageBuffer).resize({ width: 200, height: 200, withoutEnlargement: true, }).toBuffer(); logger.log("Thumbnail created"); // Prefix 'thumb_' to file name. const thumbFileName = `thumb_${fileName}`; const thumbFilePath = path.join(path.dirname(filePath), thumbFileName); // Upload the thumbnail. const metadata = {contentType: contentType}; await bucket.file(thumbFilePath).save(thumbnailBuffer, { metadata: metadata, }); return logger.log("Thumbnail uploaded!");
このコードは、ImageMagick
コマンドライン プログラム convert
を実行し、一時ディレクトリに保存される画像のサムネイル(200x200)を作成します。さらに、それを Cloud Storage に再アップロードします。
詳しくは、Google Cloud Storage のトリガーについてのドキュメントをご覧ください。