Ampliar o Cloud Storage com o Cloud Functions


É possível acionar uma função em resposta ao upload, à atualização ou à exclusão de arquivos e pastas no Cloud Storage.

Os exemplos desta página são baseados em uma função de amostra acionada com o upload de arquivos de imagem no Cloud Storage. Essa função demonstra como acessar atributos de eventos, como baixar um arquivo para uma instância do Cloud Functions e outros princípios básicos do gerenciamento de eventos do Cloud Storage.

Para mais exemplos de casos de uso, consulte O que posso fazer com o Cloud Functions?

Acionar uma função em alterações do Cloud Storage

Use functions.storage para criar uma função que gerencie eventos do Cloud Storage. É possível dimensionar sua função de acordo com um bucket específico do Cloud Storage ou usar o bucket padrão. Dependendo da sua escolha, use uma das seguintes opções:

Por exemplo, a amostra do gerador de miniaturas tem como escopo o bucket padrão do projeto:

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

O Cloud Storage é compatível com estes eventos:

  • onArchive: enviado apenas depois que o controle de versões do objeto é ativado no bucket. Este evento indica que a versão ativa de um objeto se tornou uma versão arquivada por ter sido arquivada ou substituída pelo upload de um objeto de mesmo nome.
  • onDelete: enviado quando um objeto é excluído permanentemente. Isso inclui objetos que são substituídos ou são excluídos como parte da configuração do ciclo de vida do bucket. Nos buckets com o controle de versões dos objetos ativado, ele não é enviado quando um objeto é arquivado (confira onArchive), mesmo que o arquivamento ocorra usando o método storage.objects.delete.
  • onFinalize: enviado quando um novo objeto ou uma nova geração de um objeto é criada com sucesso no bucket. Isso inclui copiar ou regravar um objeto. Um upload com falha não aciona esse evento.
  • onMetadataUpdate: enviado quando os metadados de um objeto são modificados.

Defina o evento dentro do manipulador de eventos on como mostrado acima para onFinalize.

Acessar atributos de objetos do Cloud Storage

O Cloud Functions expõe vários atributos de objeto do Cloud Storage, como size e contentType, para o arquivo atualizado. O atributo "metageneration" é incrementado sempre que há uma alteração nos metadados do objeto. Para novos objetos, o valor de 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.

A amostra de geração de miniaturas usa alguns desses atributos para detectar casos de saída em que a função retorna:

// 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.');
}

Fazer o download, transformar e fazer upload de um arquivo

Para alguns casos, pode não ser necessário baixar arquivos do Cloud Storage. Mas, para executar tarefas intensivas, como gerar uma imagem de miniatura usando um arquivo armazenado no Cloud Storage, é necessário baixar os arquivos para a instância das funções, ou seja, para a máquina virtual que executa seu código.

Para baixar e fazer novo upload de objetos com facilidade no Cloud Storage, instale o pacote do Google Cloud Storage usando npm install --save @google-cloud/storage e importe-o. Para usar promessas de JavaScript a fim de gerenciar processos externos, como tarefas de processamento de miniaturas na amostra, importe também 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');

Use gcs.bucket.file(filePath).download para baixar um arquivo em um diretório temporário na instância do Cloud Functions. Nesse local, é possível processar o arquivo conforme necessário e depois fazer upload para o Cloud Storage. Ao executar tarefas assíncronas, retorne uma promessa de JavaScript na callback.

Exemplo: transformação de imagem

Ao usar o Cloud Functions com programas de processamento de imagens como o sharp, é possível fazer manipulações em arquivos de imagens gráficas. Veja abaixo um exemplo de como criar uma imagem em miniatura para um arquivo de imagem:

// 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!");

Esse código cria uma miniatura de 200x200 para a imagem salva em um diretório temporário e, em seguida, faz upload dela de volta ao Cloud Storage.

Ver mais exemplos

Conheça outros exemplos de funções comuns de transformação de mídia, incluindo transcodificação de imagens, moderação de conteúdo e extração de metadados EXIF (todos em inglês). A lista completa de exemplos (em inglês) está disponível no GitHub.