使用 Cloud Functions 函数扩展 Cloud Storage 功能


您可以触发一个函数来响应 Cloud Storage 中上传、更新或删除文件和文件夹的操作。

本页中的示例基于一个在图片文件上传到 Cloud Storage 时触发的示例函数。此示例函数演示了如何访问事件属性、如何将文件下载到 Cloud Functions 实例,以及其他有关处理 Cloud Storage 事件的基础操作。

如需查看更多使用场景示例,请参阅Cloud Functions 有哪些用途?”

在发生 Cloud Storage 更改时触发函数

使用 functions.storage 创建一个处理 Cloud Storage 事件的函数。根据您是要将函数范围限定在特定的 Cloud Storage 存储桶还是使用默认存储桶,请使用下列选项之一:

例如,缩略图生成器示例的范围限定至项目的默认存储分区:

exports.firstGenGenerateThumbnail = functions.storage.object().onFinalize(async (object) => {
  // ...
});

Cloud Storage 支持以下事件:

  • onArchive:仅在存储桶已启用对象版本控制时发送。此事件表明某个对象的当前版本已变为归档版本,原因可能是该对象已归档,或者已被新上传的同名对象覆盖。
  • onDelete:当某个对象被永久删除时发送。这包括系统根据存储桶的生命周期配置所覆盖或删除的对象。对于启用了对象版本控制的存储桶,如果某个对象已归档(请参阅 onArchive),则系统不会发送此事件,即使通过 storage.objects.delete 方法进行归档也是如此。
  • onFinalize:当存储桶中成功创建了新对象(或现有对象的新实例)时发送。这包括复制或重写现有的对象。上传失败不会触发此事件。
  • onMetadataUpdate:当现有对象的元数据发生更改时发送。

请在 on 事件处理程序内设置事件,如上文 onFinalize 的说明中所示。

访问 Cloud Storage 对象属性

Cloud Functions 公开了多个 Cloud Storage 对象属性,例如已更新文件的 sizecontentType。每当对象的元数据发生变化时,metageneration 属性的值都会递增。对于新对象,metageneration 值为 1

const fileBucket = object.bucket; // The Storage bucket that contains the file.
const filePath = object.name; // File path in the bucket.
const contentType = object.contentType; // File content type.

缩略图生成器示例使用了这样的一些属性来检测要让函数返回的退出情况:

// Exit if this is triggered on a file that is not an image.
if (!contentType.startsWith('image/')) {
  return functions.logger.log('This is not an image.');
}

// Get the file name.
const fileName = path.basename(filePath);
// Exit if the image is already a thumbnail.
if (fileName.startsWith('thumb_')) {
  return functions.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 functions = require('firebase-functions/v1');
const admin = require('firebase-admin');
admin.initializeApp()
const path = require('path');

//library for resizing images
const sharp = require('sharp');

使用 gcs.bucket.file(filePath).download 可将文件下载到 Cloud Functions 实例的临时目录中。在此位置,您可以根据需要处理文件,然后将处理的结果上传到 Cloud Storage。执行异步任务时,请确保在回调中返回 JavaScript promise。

示例:图片转换

可以将 Cloud Functionssharp 等图片处理程序结合使用,对图片文件执行各种操作。以下示例说明了如何为上传的图片文件创建缩略图:

// Download file from bucket.
const bucket = admin.storage().bucket(fileBucket);
const metadata = {
  contentType: contentType,
};
const downloadResponse = await bucket.file(filePath).download();
const imageBuffer = downloadResponse[0];
functions.logger.log("Image downloaded!");

// Generate a thumbnail using sharp.
const thumbnailBuffer = await sharp(imageBuffer).resize({
  width: 200,
  height: 200,
  withoutEnlargement: true,
}).toBuffer();
functions.logger.log("Thumbnail created");

// Upload the thumbnail with a 'thumb_' prefix.
const thumbFileName = `thumb_${fileName}`;
const thumbFilePath = path.join(path.dirname(filePath), thumbFileName);
await bucket.file(thumbFilePath).save(thumbnailBuffer, {
  metadata: metadata,
});
return functions.logger.log("Thumbnail uploaded!");

上面这段代码会为保存在临时目录中的图片创建大小为 200x200 的缩略图,然后将缩略图传回 Cloud Storage

浏览更多示例

常见媒体转换函数的更多示例包括图片转码内容审核EXIF 元数据提取。您可在 GitHub 上找到完整的示例列表