Trigger di Cloud Storage


Puoi attivare una funzione in risposta al caricamento, all'aggiornamento eliminazione di file e cartelle in Cloud Storage.

Gli esempi in questa pagina si basano su una funzione di esempio che si attiva quando i file di immagini vengono caricati in Cloud Storage. Questa funzione di esempio dimostra come accedere agli attributi degli eventi, come scaricare un file su un Cloud Functions istanza e altre nozioni fondamentali sulla gestione degli eventi Cloud Storage.

Importa i moduli richiesti

Per iniziare, importa il modulo richiesto per la gestione di Cloud Storage eventi:

Node.js

 const {onObjectFinalized} = require("firebase-functions/v2/storage");

Python

 from firebase_functions import storage_fn

Per creare l'esempio completo, aggiungi anche le dipendenze per Firebase Admin SDK e strumenti di elaborazione delle immagini:

Node.js

 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();

Python

 import io
import pathlib

from PIL import Image

from firebase_admin import initialize_app

initialize_app()
from firebase_admin import storage

Definire l'ambito di una funzione Cloud Storage

Utilizza il seguente pattern per definire l'ambito in uno specifico bucket Cloud Storage e imposta le opzioni desiderate:

Node.js

// scope handler to a specific bucket, using storage options parameter
export archivedopts = onObjectArchived({ bucket: "myBucket" }, (event) => {
  //…
});

Python

# Scope handler to a specific bucket using storage options parameter
@storage_fn.on_object_archived(bucket="myBucket")
def archived_bucket(event: storage_fn.CloudEvent[storage_fn.StorageObjectData]):
    # ...

Al contrario, la funzione di generazione di miniature di esempio ha come ambito il bucket predefinito per del progetto:

Node.js

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

Python

@storage_fn.on_object_archived()
def generatethumbnail(event: storage_fn.CloudEvent[storage_fn.StorageObjectData]):
    # ...

Imposta la posizione della funzione

Una mancata corrispondenza tra possono causare errori di deployment. Inoltre, la distanza tra la posizione di un bucket Cloud Storage e la posizione della funzione può creare una latenza di rete significativa. Per evitare queste situazioni, specifica la posizione della funzione in modo che corrisponde alla località del bucket/trigger in uno dei seguenti modi:

  • La località della funzione corrisponde a quella del trigger
  • La località della funzione è all'interno della località del trigger (quando la regione del trigger è doppia/multiregionale)
  • La funzione può trovarsi in qualsiasi località se la regione del trigger è impostata su us-central1

Gestire gli eventi Cloud Storage

Sono disponibili i seguenti gestori per rispondere agli eventi Cloud Storage:

Node.js

  • onObjectArchived Inviata solo quando è abilitato un bucket controllo delle versioni degli oggetti. Questo evento indica che la versione live di un oggetto è diventata archiviata, perché era archiviata o era sovrascritto dal caricamento di un oggetto con lo stesso nome.
  • onObjectDeleted Inviata quando un oggetto è stato eliminato definitivamente. Questo include gli oggetti che vengono sovrascritti o eliminati come parte del configurazione del ciclo di vita. Per i bucket con controllo delle versioni degli oggetti abilitato, non viene inviato quando un oggetto viene archiviato (vedi onArchive), anche se l'archiviazione avviene tramite il metodo storage.objects.delete.
  • onObjectFinalized inviato quando un nuovo oggetto (o una nuova generazione di un esistente) è stato creato correttamente nel bucket. Ciò include la copia o riscrivere un oggetto esistente. Questo evento non viene attivato da un caricamento non riuscito.
  • onMetadataUpdated Inviato quando vengono modificati i metadati di un oggetto esistente.

Python

  • on_object_archived Inviata solo quando è abilitato un bucket controllo delle versioni degli oggetti. Questo evento indica che la versione live di un oggetto è diventata archiviata, perché era archiviata o era sovrascritto dal caricamento di un oggetto con lo stesso nome.
  • on_object_deleted Inviato quando un oggetto è stato eliminato definitivamente. Sono considerate eliminazioni definitive anche la sovrascrittura o l'eliminazione di oggetti nell'ambito della configurazione del ciclo di vita del bucket. Per i bucket con controllo delle versioni degli oggetti abilitato, non viene inviato quando un oggetto viene archiviato (vedi onArchive), anche se l'archiviazione avviene tramite il metodo storage.objects.delete.
  • on_object_finalized inviato quando un nuovo oggetto (o una nuova generazione di un esistente) è stato creato correttamente nel bucket. Ciò include la copia o riscrivere un oggetto esistente. Questo evento non viene attivato da un caricamento non riuscito.
  • on_metadata_updated Inviato in caso di variazioni nei metadati di un oggetto esistente.

Accedi agli attributi dell'oggetto Cloud Storage

Cloud Functions espone una serie di attributi dell'oggetto Cloud Storage come le dimensioni e il tipo di contenuti del file aggiornato. metageneration viene incrementato ogni volta che viene apportata una modifica all'attributo metadati dell'oggetto. Per i nuovi oggetti, il valore metageneration è 1.

Node.js

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.

Python

bucket_name = event.data.bucket
file_path = pathlib.PurePath(event.data.name)
content_type = event.data.content_type

L'esempio di generazione delle miniature utilizza alcuni di questi attributi per rilevare l'uscita casi in cui la funzione restituisce:

Node.js

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

Python

# Exit if this is triggered on a file that is not an image.
if not content_type or not content_type.startswith("image/"):
    print(f"This is not an image. ({content_type})")
    return

# Exit if the image is already a thumbnail.
if file_path.name.startswith("thumb_"):
    print("Already a thumbnail.")
    return

Scaricare, trasformare e caricare un file

In alcuni casi, potrebbe non essere necessario scaricare file da Cloud Storage. Tuttavia, per eseguire attività intensive come la generazione di un'immagine in miniatura da un file archiviato in Cloud Storage, devi scaricare i file nell'istanza di funzioni, ovvero nella macchina virtuale che esegue il tuo codice.

Utilizzo di Cloud Functions insieme a programmi di elaborazione delle immagini come sharp per Node.js e Pillow per Python, puoi eseguire manipolazioni sui file di immagine grafica. Di seguito è riportato un esempio di come crea un'immagine in miniatura per un file immagine caricato:

Node.js

/**
 * When an image is uploaded in the Storage bucket,
 * generate a thumbnail automatically using sharp.
 */
exports.generateThumbnail = onObjectFinalized({cpu: 2}, async (event) => {

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

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

Scarica il file in una directory provvisoria sull'istanza Cloud Functions. In questa posizione puoi elaborare il file come necessario e poi caricarlo su Cloud Storage. Quando eseguire attività asincrone, assicurati di restituire una promessa JavaScript nel di Google.

Python

@storage_fn.on_object_finalized()
def generatethumbnail(event: storage_fn.CloudEvent[storage_fn.StorageObjectData]):
    """When an image is uploaded in the Storage bucket, generate a thumbnail
    automatically using Pillow."""

    bucket_name = event.data.bucket
    file_path = pathlib.PurePath(event.data.name)
    content_type = event.data.content_type

    # Exit if this is triggered on a file that is not an image.
    if not content_type or not content_type.startswith("image/"):
        print(f"This is not an image. ({content_type})")
        return

    # Exit if the image is already a thumbnail.
    if file_path.name.startswith("thumb_"):
        print("Already a thumbnail.")
        return

    bucket = storage.bucket(bucket_name)

    image_blob = bucket.blob(str(file_path))
    image_bytes = image_blob.download_as_bytes()
    image = Image.open(io.BytesIO(image_bytes))

    image.thumbnail((200, 200))
    thumbnail_io = io.BytesIO()
    image.save(thumbnail_io, format="png")
    thumbnail_path = file_path.parent / pathlib.PurePath(f"thumb_{file_path.stem}.png")
    thumbnail_blob = bucket.blob(str(thumbnail_path))
    thumbnail_blob.upload_from_string(thumbnail_io.getvalue(), content_type="image/png")

Questo codice crea un'immagine in miniatura di 200 x 200 per l'immagine salvata in una directory temporanea, quindi la ricarica su Cloud Storage.