Gatilhos do Cloud Storage

Você pode 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 fazer o download de um arquivo para uma instância do Cloud Functions e outros princípios básicos do gerenciamento de eventos do Cloud Storage.

Acionar uma função quando há alterações no Cloud Storage

Use o subpacote firebase-functions/v2/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:

// 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) => {
  //…
});

Em contrapartida, a função de gerador de miniaturas é dimensionada de acordo com o bucket padrão do projeto:

exports.generateThumbnail = onObjectFinalized({cpu: 2}, async (event) => {
  // ...
});

Como definir o local da função

Importante: a distância entre o local de um bucket do Cloud Storage e o local da função pode criar uma latência de rede significativa. Além disso, uma incompatibilidade entre locais pode resultar em falha na implantação. Para evitar essas situações, especifique o local da função para que corresponda ao local do bucket/acionador de uma das seguintes maneiras:

  • O local da função é igual ao local do gatilho
  • O local da função está dentro do local do gatilho (quando a região do gatilho é dual/multirregional)
  • A função poderá estar em qualquer local se a região do gatilho estiver definida como us-central1

Como processar eventos do Cloud Storage

O Cloud Storage é compatível com os seguintes eventos:

Estes gerenciadores para responder a eventos do Cloud Storage estão disponíveis:

  • onObjectArchived: 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, podendo ter sido arquivada ou substituída pelo upload de um objeto de mesmo nome.
  • onObjectDeleted: enviado quando um objeto é excluído permanentemente. Isso inclui objetos que são substituídos ou excluídos como parte da configuração do ciclo de vida do bucket. Nos buckets com o controle de versões de objetos ativado, ele não é enviado quando um objeto é arquivado (ver onArchive), mesmo que o arquivamento ocorra pelo método storage.objects.delete.
  • onObjectFinalized: enviado quando um novo objeto ou nova geração de um objeto é criada com sucesso no bucket. Isso inclui copiar ou reescrever um objeto. Um upload com falha não aciona esse evento.
  • onMetadataUpdated: enviado quando os metadados de um objeto são alterados.

Acessar atributos de objetos do Cloud Storage

O Cloud Functions fornece ao arquivo atualizado diversos atributos de objeto do Cloud Storage, como size e contentType. O atributo metageneration será incrementado sempre que houver uma alteração nos metadados do objeto. Para novos objetos, o valor de 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.

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

Fazer o download, transformar e fazer upload de um arquivo

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

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

Use o gcs.bucket.file(filePath).download para fazer o download de um arquivo para um diretório temporário na sua instância do Cloud Functions. Nesse local, é possível processar o arquivo conforme necessário e depois fazer o 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 ImageMagick, é possível fazer manipulações em arquivos de imagens gráficas. Confira abaixo um exemplo de como criar uma imagem de miniatura para um arquivo:

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

Esse código executa o programa de linha de comando convert do ImageMagick para criar uma miniatura de 200x200 da imagem salva em um diretório temporário e, em seguida, fazer upload da imagem de volta ao Cloud Storage.

Para mais informações, consulte a documentação completa de gatilhos do Google Cloud Storage.