Wyzwalacze Cloud Storage


Możesz uruchomić funkcję w odpowiedzi na przesłanie, aktualizację lub usunięcie plików i folderów w Cloud Storage.

Przykłady na tej stronie opierają się na przykładowej funkcji, która uruchamia się po przesłaniu plików obrazów do Cloud Storage. Ta przykładowa funkcja pokazuje, jak uzyskać dostęp do atrybutów zdarzeń, jak pobrać plik do instancji Cloud Functions i inne podstawy obsługi zdarzeń Cloud Storage.

Zaimportuj wymagane moduły

Aby rozpocząć, zaimportuj moduł wymagany do obsługi zdarzeń Cloud Storage:

Node.js

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

Pyton

 from firebase_functions import storage_fn

Aby zbudować pełną próbkę, dodaj także zależności dla pakietu Firebase Admin SDK i narzędzi do przetwarzania obrazu:

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

Pyton

 import io
import pathlib

from PIL import Image

from firebase_admin import initialize_app

initialize_app()
from firebase_admin import storage

Określ zakres funkcji Cloud Storage

Użyj poniższego wzorca, aby ograniczyć swoją funkcję do określonego segmentu Cloud Storage i ustawić dowolne opcje:

Node.js

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

Pyton

# 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]):
    # ...

Natomiast przykładowa funkcja generatora miniatur jest ograniczona do domyślnego segmentu projektu:

Node.js

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

Pyton

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

Ustaw lokalizację funkcji

Niezgodność między lokalizacjami może spowodować niepowodzenie wdrożenia. Ponadto odległość między lokalizacją zasobnika Cloud Storage a lokalizacją funkcji może powodować znaczne opóźnienia w sieci. Aby uniknąć takich sytuacji, określ lokalizację funkcji tak, aby odpowiadała lokalizacji zasobnika/wyzwalacza w jeden z następujących sposobów:

  • Lokalizacja funkcji jest taka sama jak lokalizacja wyzwalacza
  • Lokalizacja funkcji znajduje się wewnątrz lokalizacji wyzwalania (gdy obszar wyzwalania jest obszarem podwójnym/wielokierunkowym)
  • Funkcja może znajdować się w dowolnym miejscu, jeśli region wyzwalania jest ustawiony na us-central1

Obsługuj zdarzenia Cloud Storage

Dostępne są następujące procedury obsługi odpowiadające na zdarzenia Cloud Storage:

Node.js

  • onObjectArchived Wysyłane tylko wtedy, gdy zasobnik włączył wersjonowanie obiektów . To zdarzenie wskazuje, że aktywna wersja obiektu stała się wersją zarchiwizowaną, ponieważ została zarchiwizowana lub została nadpisana przez przesłanie obiektu o tej samej nazwie.
  • onObjectDeleted Wysyłane, gdy obiekt został trwale usunięty. Obejmuje to obiekty, które zostały nadpisane lub usunięte w ramach konfiguracji cyklu życia zasobnika. W przypadku zasobników z włączoną wersjonowaniem obiektów nie jest to wysyłane, gdy obiekt jest archiwizowany (zobacz onArchive ), nawet jeśli archiwizacja odbywa się za pomocą metody storage.objects.delete .
  • onObjectFinalized Wysyłane, gdy w zasobniku pomyślnie utworzono nowy obiekt (lub nową generację istniejącego obiektu). Obejmuje to kopiowanie lub przepisywanie istniejącego obiektu. Nieudane przesyłanie nie powoduje wyzwolenia tego zdarzenia.
  • onMetadataUpdated Wysyłane w przypadku zmiany metadanych istniejącego obiektu.

Pyton

  • on_object_archived Wysyłane tylko wtedy, gdy zasobnik włączył wersjonowanie obiektów . To zdarzenie wskazuje, że aktywna wersja obiektu stała się wersją zarchiwizowaną, ponieważ została zarchiwizowana lub została nadpisana przez przesłanie obiektu o tej samej nazwie.
  • on_object_deleted Wysyłane, gdy obiekt został trwale usunięty. Obejmuje to obiekty, które zostały nadpisane lub usunięte w ramach konfiguracji cyklu życia zasobnika. W przypadku zasobników z włączoną wersjonowaniem obiektów nie jest to wysyłane, gdy obiekt jest archiwizowany (zobacz onArchive ), nawet jeśli archiwizacja odbywa się za pomocą metody storage.objects.delete .
  • on_object_finalized Wysyłane, gdy w zasobniku pomyślnie utworzono nowy obiekt (lub nową generację istniejącego obiektu). Obejmuje to kopiowanie lub przepisywanie istniejącego obiektu. Nieudane przesyłanie nie powoduje wyzwolenia tego zdarzenia.
  • on_metadata_updated Wysyłane w przypadku zmiany metadanych istniejącego obiektu.

Uzyskaj dostęp do atrybutów obiektu Cloud Storage

Cloud Functions udostępnia szereg atrybutów obiektu Cloud Storage, takich jak rozmiar obiektu i typ zawartości aktualizowanego pliku. Atrybut metageneration jest zwiększany za każdym razem, gdy nastąpi zmiana w metadanych obiektu. Dla nowych obiektów wartość metageneration wynosi 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.

Pyton

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

Przykład generowania miniatur wykorzystuje niektóre z tych atrybutów do wykrywania przypadków wyjścia, w których funkcja zwraca:

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

Pyton

# 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

Pobierz, przekształć i prześlij plik

W niektórych przypadkach pobieranie plików z Cloud Storage może nie być konieczne. Aby jednak wykonywać intensywne zadania, takie jak generowanie miniatury z pliku przechowywanego w Cloud Storage, musisz pobrać pliki do instancji funkcji, czyli maszyny wirtualnej, na której uruchamiany jest Twój kod.

Używając Cloud Functions wraz z programami do przetwarzania obrazów, takimi jak sharp dla Node.js i Pillow dla Pythona, możesz wykonywać manipulacje na plikach obrazów graficznych. Poniżej znajduje się przykład tworzenia miniatury przesłanego pliku obrazu:

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

Pobierz plik do katalogu tymczasowego w instancji Cloud Functions. W tej lokalizacji możesz w razie potrzeby przetworzyć plik, a następnie przesłać go do Cloud Storage. Wykonując zadania asynchroniczne, pamiętaj o zwróceniu obietnicy JavaScript w wywołaniu zwrotnym.

Pyton

@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")

Ten kod tworzy miniaturę obrazu o wymiarach 200x200 zapisanego w katalogu tymczasowym, a następnie przesyła ją z powrotem do Cloud Storage.