Firebase Cloud Functions — to platforma serwerowa do wykonywania kodu w zarządzanym środowisku Node.js, która reaguje na zdarzenia Firebase, żądania HTTPS oraz zmiany w usługach chmurowych Google. W przeciwieństwie do tradycyjnego backendu, programista nie musi konfigurować serwera, instalować serwera WWW ani martwić się o skalowanie — każda funkcja działa w izolowanym kontenerze i automatycznie otrzymuje tyle zasobów, ile potrzebuje. Według Google Firebase (2026), platforma obsługuje ponad 2 miliardy wywołań funkcji dziennie, zapewniając architekturę bezserwerową dla milionów aplikacji mobilnych.
Najważniejsze
Firebase Cloud Functions — to platforma obliczeniowa zbudowana na bazie Google Cloud Functions (GCF), dostosowana do ekosystemu Firebase. Funkcje to zwykły kod JavaScript lub TypeScript, eksportowany z modułu i rejestrowany dla określonego typu zdarzenia. Gdy zdarzenie wystąpi (na przykład użytkownik się rejestruje lub przesyła plik), Firebase Cloud Functions uruchamia odpowiedni kod, przekazując mu kontekst zdarzenia.
Architektura Cloud Functions kieruje się zasadą pojedynczej odpowiedzialności: jedna funkcja obsługuje jeden typ zdarzenia i wykonuje jedną atomową operację. Na przykład funkcja sendWelcomeEmail jest wywoływana przy utworzeniu nowego użytkownika w Firebase Authentication i wysyła wiadomość powitalną. Taka izolacja upraszcza debugowanie, testowanie i ponowne wykorzystanie funkcji w różnych projektach.
Każda funkcja działa w izolowanym kontenerze o tymczasowym cyklu życia. Maksymalny czas wykonania domyślnie wynosi 60 sekund (funkcje HTTPS — 9 minut). Jeśli funkcja nie zmieści się w limicie czasu, żądanie kończy się błędem 500. W przypadku długich operacji użyj Cloud Tasks lub Pub/Sub z ponownymi próbami. Kontenery mogą być ponownie używane dla kolejnych wywołań (keep-alive), co zmniejsza opóźnienia przy zimnych startach po pierwszym wywołaniu.
Firebase Cloud Functions obsługują kilka wersji Node.js: 18, 20 i 22 (zalecana dla nowych projektów). Wybór wersji ustawia się w polu engines pliku package.json. Firebase CLI automatycznie konfiguruje środowisko wykonawcze na podstawie wskazanej wersji. Ważne: Firebase Cloud Functions nie obsługują uruchamiania dowolnych kontenerów Docker — środowisko jest ściśle ustalone przez Google Cloud Functions.
W przypadku nowych projektów zalecany jest Node.js 22, ponieważ zawiera najnowsze optymalizacje V8, ulepszoną obsługę modułów ESM i wsparcie WebSocket na poziomie platformy. Jeśli projekt używa zależności zbudowanych dla konkretnej wersji Node (na przykład natywnych modułów C++), kompatybilność należy sprawdzić osobno — nie wszystkie natywne moduły kompilują się w środowisku GCF.
Firebase Cloud Functions — to nakładka na Google Cloud Functions z preinstalowanym Firebase SDK i integracją z usługami Firebase. Programista pisze kod przy użyciu SDK firebase-functions, które udostępnia typowane wyzwalacze dla wszystkich usług Firebase. Google Cloud Functions to platforma niższego poziomu, gdzie wyzwalacze konfiguruje się jawnie przez Eventarc lub Pub/Sub.
Kluczowa różnica: w Firebase Cloud Functions wyzwalacz jest rejestrowany deklaratywnie przez wywołanie functions.firestore.document('path').onWrite(), a w Google Cloud Functions — przez konfigurację Eventarc z filtrowaniem po atrybutach zdarzenia. Firebase Cloud Functions jest również automatycznie dostarczany z Admin SDK, zainicjalizowanym z uprawnieniami konta usługi projektu, co daje pełny dostęp do wszystkich usług Firebase bez dodatkowej konfiguracji.
Firebase Cloud Functions obsługuje 8 kategorii wyzwalaczy, z których każda odpowiada określonej usłudze Firebase lub Google Cloud. Wyzwalacz to warunek, po wystąpieniu którego funkcja jest wywoływana automatycznie. Programista nie zarządza bezpośrednio cyklem życia funkcji: Firebase CLI rejestruje wyzwalacz w Google Cloud Eventarc, a platforma chmurowa sama uruchamia funkcję, gdy zdarzenie wystąpi.
Najpopularniejsze wyzwalacze to wyzwalacze Firestore: onWrite, onCreate, onUpdate, onDelete. Są uruchamiane przy zmianie dokumentów w kolekcjach Firestore. Funkcja otrzymuje migawki dokumentu przed i po zmianie, co pozwala porównywać wartości i reagować tylko na określone zmiany. Na przykład przy zmianie statusu zamówienia z „pending” na „shipped” można wysłać powiadomienie push do użytkownika.
Wyzwalacze Authentication (onCreate, onDelete) są uruchamiane przy utworzeniu lub usunięciu konta. Służą do inicjalizacji danych użytkownika: tworzenia dokumentu użytkownika w Firestore, wysyłania e-maila powitalnego, zapisu do analityki. Ważne: funkcja nie może anulować utworzenia użytkownika — działa po tym, jak konto już zostało utworzone. Do wstępnej walidacji używaj funkcji blokujących (Blocking Functions), dostępnych na platformie Identity Platform.
| Kategoria wyzwalacza | Zdarzenie | Przykład użycia |
|---|---|---|
| Firestore | onWrite, onCreate, onUpdate, onDelete | Aktualizacja licznika polubień przy dodaniu |
| Authentication | onCreate, onDelete | Tworzenie profilu użytkownika przy rejestracji |
| Realtime DB | onWrite, onCreate, onUpdate, onDelete | Moderacja wiadomości na czacie |
| Storage | onFinalize, onArchive, onDelete | Generowanie miniatury po przesłaniu obrazu |
| Pub/Sub | onPublish | Okresowe uruchamianie (cron) przez Cloud Scheduler |
| HTTPS | onRequest | Punkt końcowy REST API dla usług zewnętrznych |
Funkcje HTTPS (onRequest) pozwalają tworzyć pełnoprawne punkty końcowe REST API dostępne przez HTTP. W przeciwieństwie do wyzwalaczy zdarzeń, funkcje HTTPS są wywoływane przez URL w formacie https://{region}-{project}.cloudfunctions.net/{functionName}. Ważne jest prawidłowe skonfigurowanie CORS, jeśli punkt końcowy jest wywoływany z przeglądarki lub aplikacji mobilnej. Firebase SDK nie dodaje automatycznie nagłówków CORS — należy je dodać ręcznie przez middleware.
Dla klientów mobilnych (Android, iOS) CORS nie jest wymagany, ponieważ natywne klienty HTTP nie są ograniczone polityką Cross-Origin. CORS ma znaczenie tylko dla żądań z sieci. Jeśli funkcja HTTPS jest wywoływana zarówno z aplikacji, jak i z sieci, dodaj uniwersalną obsługę CORS: res.set('Access-Control-Allow-Origin', '*') dla development lub listę dozwolonych domen dla production.
Do okresowego wykonywania (zadań cron) używaj kombinacji Cloud Scheduler i Pub/Sub. Cloud Scheduler wysyła wiadomość do tematu Pub/Sub zgodnie z harmonogramem, a wyzwalacz Cloud Functions onPublish przetwarza tę wiadomość. Firebase CLI nie obsługuje bezpośredniej składni cron — harmonogram ustawia się w konsoli Google Cloud lub Terraform w formacie unix-cron: 0 3 * * * (codziennie o 3:00).
Przykładowe zadania: codzienna wysyłka, czyszczenie nieaktualnych danych, generowanie raportów, synchronizacja z zewnętrznymi API. Ważne: Cloud Scheduler to płatna usługa Google Cloud (około $2 miesięcznie za jedno zadanie). Każde wyzwolenie jest liczone jako osobne wywołanie funkcji i rozliczane według standardowych cen Cloud Functions.
Tworzenie Cloud Functions zaczyna się od inicjalizacji projektu przez Firebase CLI: firebase init functions. To polecenie tworzy katalog functions/ z szablonem index.js (lub index.ts), plikiem package.json i konfiguracją TypeScript (jeśli wybrano). Po inicjalizacji wystarczy napisać funkcję, wyeksportować ją z modułu i uruchomić firebase deploy --only functions, aby ją wdrożyć.
Każda funkcja jest rejestrowana przez wywołanie metody odpowiedniego wyzwalacza. Przykład funkcji HTTPS: exports.helloWorld = functions.https.onRequest((req, res) => { res.send("Hello!"); }). Funkcje Firebase używają modelu asynchronicznego: w przypadku wyzwalaczy zdarzeń (nie HTTPS) funkcja musi zwracać Promise. Firebase czeka na zakończenie Promise przed zamknięciem kontenera. Jeśli Promise nie zostanie zwrócone, funkcja może zostać przerwana przed zakończeniem operacji asynchronicznych.
Rozwój lokalny odbywa się przez Firebase Emulator Suite, który zawiera emulator Cloud Functions. Polecenie firebase emulators:start uruchamia lokalny serwer z funkcjami, dostępny pod adresem http://localhost:5001. Emulator obsługuje gorące przeładowanie (hot reload) przy zmianie kodu i jest całkowicie odizolowany od środowiska produkcyjnego, co pozwala testować funkcje bez ryzyka wpływu na rzeczywiste dane.
Zależności Cloud Functions są zarządzane przez package.json. Firebase instaluje tylko zależności produkcyjne (dependencies, nie devDependencies). Rozmiar pakietu funkcji wpływa na czas zimnego startu: zaleca się minimalizowanie liczby zależności. Do pracy z Firebase Admin SDK zależność firebase-admin jest już preinstalowana — nie trzeba jej dodawać ręcznie.
Dane poufne (klucze API, tokeny) nie powinny być przechowywane w kodzie funkcji. Używaj functions.config() do przechowywania konfiguracji: firebase functions:config:set stripe.key="sk_...". Wartości są szyfrowane i dostępne w runtime przez functions.config().stripe.key. W przypadku dużych konfiguracji serializowanych używaj Secret Manager Google Cloud.
Logowanie w Cloud Functions odbywa się przez console.log, console.warn i console.error. Wszystkie logi są automatycznie gromadzone w Google Cloud Logging i dostępne w konsoli Firebase (sekcja Functions > Logs). Do logowania strukturalnego używaj biblioteki winston lub pino, które obsługują formatowanie JSON i poziomy logowania.
Obsługa błędów jest krytyczna dla niezawodności: nieobsłużony wyjątek w Promise kończy funkcję błędem, po czym Firebase automatycznie ponawia wywołanie (retry) z wykładniczym opóźnieniem. Liczbę prób można skonfigurować: od 0 do nieskończoności. W przypadku wyzwalaczy zdarzeń zaleca się włączenie retry, aby zagwarantować przetworzenie każdego zdarzenia nawet przy przejściowych awariach usług zewnętrznych.
Zimny start (cold start) — to opóźnienie przy pierwszym wywołaniu funkcji po okresie bezczynności, gdy kontener z kodem jest ładowany i inicjalizowany od nowa. Według Firebase documentation (2026), zimny start trwa od 200 ms do 2 sekund w zależności od rozmiaru pakietu, liczby zależności i regionu. Dla interfejsu użytkownika opóźnienie powyżej 1 sekundy jest odczuwalne i może wpływać na user experience.
Sposoby minimalizacji zimnego startu: minimalizacja zależności, używanie TypeScript z kompilacją do CommonJS, zmniejszenie rozmiaru pakietu funkcji, ustawienie minimalnej liczby aktywnych instancji. Firebase Cloud Functions v2 (2nd gen) pozwala ustawić minInstances — minimalną liczbę ogrzanych kontenerów, które zawsze są gotowe do obsługi żądań. Za ogrzewanie kontenerów pobierana jest opłata za czas bezczynności.
Skalowanie Cloud Functions odbywa się automatycznie: przy wzroście liczby żądań Firebase tworzy nowe kontenery. Domyślnie maksymalna liczba równoległych instancji wynosi 3000 (limit projektu Google Cloud). Każda instancja obsługuje jednocześnie jedno żądanie. Jeśli funkcja jest szybka (poniżej 100 ms), jedna instancja może obsłużyć do 10 żądań na sekundę, co daje szczytową przepustowość do 30 000 żądań na sekundę na projekt.
minInstances — parametr, który rezerwuje określoną liczbę kontenerów i utrzymuje je w stanie ogrzanym. Jest zalecany dla krytycznych funkcji HTTPS, gdzie opóźnienie zimnego startu jest niedopuszczalne. Na przykład dla punktu końcowego uwierzytelniania ustaw minInstances: 1. maxInstances — ograniczenie maksymalnej liczby równoległych instancji, przydatne do zapobiegania niekontrolowanemu wzrostowi kosztów przy nagłym wzroście ruchu.
Konfiguracja odbywa się w kodzie: functions.runWith({ minInstances: 1, maxInstances: 10 }). Ważne: minInstances zwiększa koszty, ponieważ kontener działa bez przerwy. W projektach testowych minInstances należy wyłączać. W produkcji zaleca się minInstances dla wszystkich publicznych funkcji HTTPS i 0 dla wyzwalaczy zdarzeń, gdzie opóźnienie 1 sekundy nie jest krytyczne.
Region wdrażania wpływa na opóźnienie do użytkowników końcowych i koszt ruchu wychodzącego. Firebase Cloud Functions jest dostępny w ponad 30 regionach Google Cloud. Dla aplikacji mobilnych wybieraj region najbliższy Twojej grupie docelowej: us-central1 dla Ameryki, europe-west1 dla Europy, asia-east2 dla Azji. Regionu nie można zmienić po wdrożeniu bez ponownego wdrożenia funkcji.
Zmiana regionu odbywa się przez parametr region w kodzie: functions.region('europe-west1'). Wszystkie funkcje w jednym pliku mogą mieć różne regiony. W projektach globalnych zaleca się wdrożenie funkcji w kilku regionach i użycie Cloud Load Balancing do dystrybucji ruchu, chociaż dla większości aplikacji mobilnych jeden region wystarcza przy prawidłowym wyborze.
Omówimy praktyczne przykłady Cloud Functions w TypeScript. Kod używa Firebase Functions SDK v2 (2nd gen) z modułową składnią ES. Przykłady obejmują obsługę zdarzenia utworzenia użytkownika, generowanie miniatury przy przesyłaniu obrazu i prosty punkt końcowy HTTPS dla REST API. Wszystkie funkcje są asynchroniczne i zwracają Promise w celu prawidłowego zakończenia kontenera.
Przed uruchomieniem upewnij się, że Firebase CLI jest zaktualizowany do wersji 13+: npm install -g firebase-tools. Funkcje v2 wymagają planu taryfowego Blaze. Inicjalizacja: firebase init functions z wyborem TypeScript.
Pierwszy przykład — tworzenie dokumentu w Firestore przy rejestracji nowego użytkownika. Funkcja jest wyzwalana zdarzeniem auth.user().onCreate i zapisuje podstawowy profil do kolekcji users/{uid}. Dzięki temu można zagwarantować, że dla każdego zarejestrowanego użytkownika istnieje dokument z niezbędnymi polami.
import * as functions from "firebase-functions"
import * as admin from "firebase-admin"
admin.initializeApp()
export const createUserProfile = functions.auth
.user()
.onCreate(async (user) => {
const profile = {
email: user.email,
displayName: user.displayName ?? "User",
createdAt: admin.firestore.Timestamp.now(),
role: "free",
avatarUrl: null,
}
await admin.firestore()
.collection("users")
.doc(user.uid)
.set(profile)
console.log(`Profile created for ${user.uid}`)
})
Funkcja createUserProfile jest asynchroniczna — zwraca Promise, którego Firebase oczekuje przed zakończeniem. Jeśli zapis do Firestore zakończy się błędem (na przykład z powodu braku uprawnień), funkcja zostanie automatycznie powtórzona (jeśli włączono retry). Pole role z wartością "free" pozwala zaimplementować ograniczenia darmowego planu bezpośrednio w Security Rules Firestore, porównując resource.data.role z wymaganym poziomem dostępu.
Drugi przykład — wyzwalacz Storage do automatycznego generowania miniatury (thumbnail) po przesłaniu obrazu. Funkcja tworzy zmniejszoną kopię o rozmiarze 200x200 pikseli i zapisuje ją pod ścieżką pliku źródłowego z prefiksem thumb_. Do przetwarzania obrazów używana jest biblioteka sharp, która obsługuje wszystkie popularne formaty i działa w środowisku Node.js bez zależności systemowych.
import * as path from "path"
import * as os from "os"
import * as sharp from "sharp"
export const generateThumbnail = functions.storage
.object()
.onFinalize(async (object) => {
if (!object.contentType?.startsWith("image/")) return
const filePath = object.name!
const thumbPath = filePath.replace(
/(\.\w+)$/, "_thumb$1"
)
const bucket = admin.storage().bucket()
const tempDir = os.tmpdir()
const tempFile = path.join(tempDir, path.basename(filePath))
await bucket.file(filePath).download({ destination: tempFile })
await sharp(tempFile)
.resize(200, 200, { fit: "cover" })
.toFile(tempFile.replace(/(\.\w+)$/, "_thumb$1"))
await bucket.upload(tempFile.replace(
/(\.\w+)$/, "_thumb$1"
), { destination: thumbPath })
})
Funkcja generateThumbnail sprawdza Content-Type obiektu i ignoruje nie-obrazy, co oszczędza zasoby. Do pracy z sharp zależność musi zostać dodana do package.json. Miniatura jest tworzona z parametrem fit: "cover", który przycina obraz do kwadratu 200x200 pikseli wyśrodkowanego. Po utworzeniu miniatura jest przesyłana z powrotem do tego samego zasobnika z zmodyfikowaną nazwą.
Trzeci przykład — funkcja HTTPS, implementująca punkt końcowy REST API do sprawdzania statusu serwera. Funkcja przyjmuje żądanie GET i zwraca JSON z informacjami o stanie usług Firebase podłączonych do projektu. Punkt końcowy jest przydatny do monitorowania oraz dla systemów zewnętrznych, które muszą sprawdzić dostępność backendu przed wysłaniem danych.
import * as express from "express"
const app = express.Router()
app.get("/status", async (req, res) => {
try {
const db = admin.firestore()
await db.collection("_health").doc("check").get()
res.json({ status: "ok", timestamp: Date.now() })
} catch (error) {
res.status(503).json({ status: "error", message: error })
}
})
export const api = functions.https.onRequest(app)
Funkcja api używa express Router do routingu, co jest wygodne przy tworzeniu kilku punktów końcowych w jednej funkcji. Health check jest zapisywany w Firestore do kolekcji _health, co pozwala jednocześnie sprawdzić dostępność Firestore. W produkcji zaleca się dodanie uwierzytelniania żądań przez klucz API lub token Firebase Auth, aby zapobiec nadużyciom publicznego punktu końcowego.
Cloud Functions najczęściej są używane do zadań, których nie można lub nie należy wykonywać na kliencie: wysyłka powiadomień push, generowanie podglądów przesłanych obrazów, integracja z zewnętrznymi systemami płatności, moderacja treści, synchronizacja danych między Firebase a usługami firm trzecich. Model bezserwerowy czyni te zadania ekonomicznymi: opłata jest pobierana tylko za rzeczywisty czas wykonywania kodu.
Integracja z systemami płatności — typowy scenariusz dla aplikacji z zakupami in-app. Cloud Functions otrzymuje webhook od dostawcy płatności (Stripe, PayPal), weryfikuje podpis żądania, aktualizuje status subskrypcji w Firestore i wysyła użytkownikowi potwierdzenie. Cały kod jest wykonywany na serwerze bez ryzyka podmiany danych na kliencie. Według Stripe documentation (2026), przetwarzanie webhooku trwa mniej niż 500 ms.
Inteligentna moderacja treści używa wyzwalacza Storage do automatycznego sprawdzania przesłanych obrazów przez Google Cloud Vision API. Funkcja wysyła obraz do Vision API w celu wykrycia niebezpiecznych treści (przemoc, treści dla dorosłych), a jeśli próg zostanie przekroczony, usuwa plik i powiadamia administratora. Ten scenariusz jest kluczowy dla aplikacji UGC z galeriami użytkowników.
Agregacja danych — Cloud Functions jako zamiennik liczników Firebase Realtime Database. Zamiast odczytu i zapisu licznika na kliencie (co prowadzi do race conditions), użyj wyzwalacza Firestore onWrite do atomowej aktualizacji zagregowanych pól. Na przykład funkcja zlicza liczbę polubień postu przy każdym dodaniu lub usunięciu dokumentu w podkolekcji /posts/{postId}/likes/{userId} i aktualizuje pole likesCount w dokumencie nadrzędnym.
Często zadawane pytania
Maksymalny czas wykonania zależy od typu: funkcje HTTPS — 9 minut, wyzwalacze zdarzeń — 60 sekund (v2: do 60 minut). W przypadku długich operacji używaj Cloud Tasks lub Pub/Sub z przetwarzaniem asynchronicznym. Limit czasu ustawia się w kodzie przez runWith({ timeoutSeconds: 120 }).
Użyj Firebase Emulator Suite: firebase emulators:start --only functions. Emulator uruchamia funkcje lokalnie na porcie 5001 z obsługą gorącego przeładowania. Dla wyzwalaczy Firestore i Auth emulator podmienia rzeczywiste usługi, pozwalając testować scenariusze bez ryzyka dla danych produkcyjnych.
2nd gen używa Google Cloud Run i Eventarc, zapewniając dłuższy limit czasu (do 60 minut), współbieżne przetwarzanie żądań przez jedną instancję i lepszą integrację z usługami Google Cloud. 1st gen używa Google Cloud Functions i jest ograniczony do 60 sekund dla funkcji zdarzeń. Firebase zaleca rozpoczynanie nowych projektów od 2nd gen.
Firebase Cloud Functions oficjalnie obsługuje tylko Node.js (JavaScript i TypeScript). Do Pythona używaj Google Cloud Functions bezpośrednio z Firebase Admin SDK dla Pythona. Firebase Admin SDK Python obsługuje wszystkie operacje, z wyjątkiem niektórych wyzwalaczy specyficznych dla Firebase, które są dostępne tylko przez Node.js.
Do uwierzytelnionego dostępu weryfikuj token Firebase ID w nagłówku Authorization: admin.auth().verifyIdToken(token). Do integracji serwer-serwer używaj Firebase Admin SDK z kontem usługi lub kluczami API. W przypadku publicznych punktów końcowych z ograniczeniem szybkości używaj rate limiting przez Cloud Armor lub middleware.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również