Firebase Cloud Functions — cos'è, trigger e come scrivere funzioni

Autore: IT Sectr Pubblicato: 2026-04-28 Tempo di lettura: 15 min

Firebase Cloud Functions è una piattaforma lato server per eseguire codice in un ambiente Node.js gestito che risponde a eventi Firebase, richieste HTTPS e modifiche ai servizi cloud di Google. A differenza del backend tradizionale, lo sviluppatore non deve configurare un server, installare un server web o preoccuparsi della scalabilità — ogni funzione viene eseguita in un contenitore isolato e ottiene automaticamente le risorse necessarie. Secondo Google Firebase (2026), la piattaforma elabora oltre 2 miliardi di chiamate di funzioni al giorno, fornendo un'architettura serverless per milioni di applicazioni mobili.

Punti chiave

  • Cloud Functions è codice lato server che viene eseguito in risposta a eventi Firebase e richieste HTTPS.
  • Modello serverless elimina la gestione dell'infrastruttura: la scalabilità avviene automaticamente.
  • Trigger includono modifiche in Firestore, Realtime Database, Storage, Authentication e Pub/Sub.
  • Linguaggio di sviluppo — JavaScript, TypeScript o Python (tramite Google Cloud Functions).
  • Avvio a freddo — la prima chiamata dopo l'inattività può richiedere fino a 2 secondi.

Cosa sono Firebase Cloud Functions e come funzionano

Firebase Cloud Functions è una piattaforma di elaborazione costruita su Google Cloud Functions (GCF), adattata per l'ecosistema Firebase. Le funzioni sono codice JavaScript o TypeScript normale esportato da un modulo e registrato per un tipo di evento specifico. Quando si verifica un evento (ad esempio, un utente si registra o carica un file), Firebase Cloud Functions esegue il codice corrispondente, passandogli il contesto dell'evento.

L'architettura di Cloud Functions segue il principio di responsabilità singola: una funzione gestisce un tipo di evento ed esegue un'operazione atomica. Ad esempio, la funzione sendWelcomeEmail viene attivata quando un nuovo utente viene creato in Firebase Authentication e invia un'email di benvenuto. Questo isolamento semplifica il debug, il test e il riutilizzo delle funzioni in diversi progetti.

Ogni funzione viene eseguita in un contenitore isolato con un ciclo di vita temporaneo. Il tempo massimo di esecuzione predefinito è di 60 secondi (funzioni HTTPS — 9 minuti). Se una funzione non viene completata entro il timeout, la richiesta fallisce con errore 500. Per operazioni di lunga durata, utilizzare Cloud Tasks o Pub/Sub con tentativi. I contenitori possono essere riutilizzati per chiamate successive (keep-alive), riducendo la latenza negli avvii a freddo dopo la prima chiamata.

Ambiente di esecuzione e versioni di Node.js

Firebase Cloud Functions supporta diverse versioni di Node.js: 18, 20 e 22 (consigliata per nuovi progetti). La versione viene specificata nel campo engines del file package.json. Firebase CLI configura automaticamente l'ambiente di esecuzione in base alla versione specificata. Importante: Firebase Cloud Functions non supporta l'esecuzione di contenitori Docker arbitrari — l'ambiente è strettamente fissato da Google Cloud Functions.

Per i nuovi progetti, si consiglia Node.js 22 poiché include le ultime ottimizzazioni V8, un supporto migliorato per i moduli ESM e il supporto WebSocket a livello di piattaforma. Se un progetto utilizza dipendenze compilate per una versione specifica di Node (ad esempio, moduli nativi C++), la compatibilità deve essere verificata individualmente — non tutti i moduli nativi vengono compilati nell'ambiente GCF.

Differenza tra Firebase Cloud Functions e Google Cloud Functions

Firebase Cloud Functions è un wrapper attorno a Google Cloud Functions con Firebase SDK preinstallato e integrazione con i servizi Firebase. Lo sviluppatore scrive codice utilizzando l'SDK firebase-functions, che fornisce trigger tipizzati per tutti i servizi Firebase. Google Cloud Functions è una piattaforma di livello inferiore in cui i trigger vengono configurati esplicitamente tramite Eventarc o Pub/Sub.

La differenza chiave: in Firebase Cloud Functions, un trigger viene registrato in modo dichiarativo tramite functions.firestore.document('path').onWrite(), mentre in Google Cloud Functions viene configurato tramite Eventarc con filtraggio degli attributi dell'evento. Firebase Cloud Functions viene inoltre fornito con Admin SDK inizializzato automaticamente con le credenziali dell'account di servizio del progetto, fornendo accesso completo a tutti i servizi Firebase senza configurazione aggiuntiva.

Tipi di trigger: quali eventi sono supportati

Firebase Cloud Functions supporta 8 categorie di trigger, ciascuna corrispondente a un servizio Firebase o Google Cloud specifico. Un trigger è una condizione che, quando viene soddisfatta, richiama automaticamente una funzione. Lo sviluppatore non gestisce direttamente il ciclo di vita della funzione: Firebase CLI registra il trigger in Google Cloud Eventarc e la piattaforma cloud esegue la funzione quando si verifica l'evento.

I trigger più popolari sono i trigger Firestore: onWrite, onCreate, onUpdate, onDelete. Si attivano quando i documenti nelle raccolte Firestore vengono modificati. La funzione riceve snapshot del documento prima e dopo la modifica, consentendo di confrontare i valori e reagire solo a modifiche specifiche. Ad esempio, quando lo stato di un ordine passa da “in attesa” a “spedito”, è possibile inviare una notifica push all'utente.

I trigger Authentication (onCreate, onDelete) si attivano quando un account utente viene creato o eliminato. Vengono utilizzati per inizializzare i dati dell'utente: creare un documento utente in Firestore, inviare un'email di benvenuto, scrivere in analytics. Nota: la funzione non può annullare la creazione dell'utente — viene eseguita dopo che l'account è già stato creato. Per la pre-convalida, utilizzare le Blocking Functions disponibili su Identity Platform.

Categoria di triggerEventoEsempio di utilizzo
FirestoreonWrite, onCreate, onUpdate, onDeleteAggiornare il contatore dei like quando se ne aggiunge uno
AuthenticationonCreate, onDeleteCreare il profilo utente al momento della registrazione
Realtime DBonWrite, onCreate, onUpdate, onDeleteModerazione dei messaggi in chat
StorageonFinalize, onArchive, onDeleteGenerare una miniatura dopo il caricamento di un'immagine
Pub/SubonPublishEsecuzione pianificata (cron) tramite Cloud Scheduler
HTTPSonRequestEndpoint API REST per servizi esterni

Trigger HTTPS e CORS

Le funzioni HTTPS (onRequest) consentono di creare endpoint API REST completi accessibili tramite HTTP. A differenza dei trigger basati su eventi, le funzioni HTTPS vengono richiamate tramite un URL del tipo https://{region}-{project}.cloudfunctions.net/{functionName}. È importante configurare correttamente il CORS se l'endpoint viene chiamato da un browser o da un'applicazione mobile. Firebase SDK non include automaticamente le intestazioni CORS — devono essere aggiunte manualmente tramite middleware.

Per i client mobili (Android, iOS), il CORS non è necessario poiché i client HTTP nativi non sono limitati dalla politica Cross-Origin. Il CORS è rilevante solo per le richieste web. Se la tua funzione HTTPS viene chiamata sia dall'app che dal web, aggiungi una gestione CORS universale: res.set('Access-Control-Allow-Origin', '*') per lo sviluppo o un elenco di domini consentiti per la produzione.

Pianificazione con Pub/Sub e Cloud Scheduler

Per l'esecuzione periodica (attività cron), utilizzare una combinazione di Cloud Scheduler e Pub/Sub. Cloud Scheduler invia un messaggio a un topic Pub/Sub secondo una pianificazione e il trigger onPublish di Cloud Functions elabora quel messaggio. Firebase CLI non supporta la sintassi cron diretta — la pianificazione viene configurata tramite la console Google Cloud o Terraform in formato unix-cron: 0 3 * * * (ogni giorno alle 3:00).

Esempi di attività: newsletter giornaliera, pulizia dei dati obsoleti, generazione di report, sincronizzazione con API esterne. Importante: Cloud Scheduler è un servizio a pagamento di Google Cloud (circa $2 al mese per lavoro). Ogni attivazione conta come una chiamata di funzione separata e viene fatturata secondo le tariffe standard di Cloud Functions.

Come scrivere e distribuire funzioni

Lo sviluppo di Cloud Functions inizia con l'inizializzazione di un progetto tramite Firebase CLI: firebase init functions. Questo comando crea una directory functions/ con un modello index.js (o index.ts), un file package.json e la configurazione TypeScript (se selezionato). Dopo l'inizializzazione, basta scrivere una funzione, esportarla dal modulo ed eseguire firebase deploy --only functions per distribuirla.

Ogni funzione viene registrata chiamando il metodo di trigger appropriato. Esempio di una funzione HTTPS: exports.helloWorld = functions.https.onRequest((req, res) => { res.send(“Hello!”); }). Firebase Functions utilizza un modello asincrono: per i trigger basati su eventi (non HTTPS), la funzione deve restituire una Promise. Firebase attende il completamento della Promise prima di terminare il contenitore. Se una Promise non viene restituita, la funzione potrebbe essere terminata prima del completamento delle operazioni asincrone.

Lo sviluppo locale viene eseguito tramite Firebase Emulator Suite, che include un emulatore di Cloud Functions. Il comando firebase emulators:start avvia un server locale con funzioni accessibili all'indirizzo http://localhost:5001. L'emulatore supporta il ricaricamento a caldo quando il codice cambia ed è completamente isolato dall'ambiente di produzione, consentendo test senza rischi per i dati reali.

Gestione delle dipendenze e della configurazione

Le dipendenze di Cloud Functions sono gestite tramite package.json. Firebase installa solo le dipendenze di produzione (dependencies, non devDependencies). La dimensione del pacchetto di funzioni influisce sul tempo di avvio a freddo: si consiglia di ridurre al minimo il numero di dipendenze. La dipendenza firebase-admin è preinstallata per Firebase Admin SDK — non è necessario aggiungerla manualmente.

I dati riservati (chiavi API, token) non devono essere memorizzati nel codice della funzione. Utilizzare functions.config() per memorizzare la configurazione: firebase functions:config:set stripe.key=“sk_...”. I valori sono crittografati e disponibili in fase di esecuzione tramite functions.config().stripe.key. Per configurazioni serializzate di grandi dimensioni, utilizzare Google Cloud Secret Manager.

Gestione degli errori e registrazione

La registrazione in Cloud Functions viene effettuata tramite console.log, console.warn e console.error. Tutti i log vengono automaticamente raccolti in Google Cloud Logging e sono disponibili nella console Firebase (Functions > Logs). Per la registrazione strutturata, utilizzare le librerie winston o pino, che supportano la formattazione JSON e i livelli di log.

La gestione degli errori è fondamentale per l'affidabilità: un'eccezione non gestita in una Promise termina la funzione con un errore, dopodiché Firebase riprova automaticamente con backoff esponenziale. Il numero di tentativi è configurabile: da 0 a infinito. Per i trigger basati su eventi, si consiglia di attivare i tentativi per garantire che ogni evento venga elaborato anche durante guasti temporanei dei servizi esterni.

Avvio a freddo e scalabilità

L'avvio a freddo (cold start) è il ritardo nella prima invocazione di una funzione dopo un periodo di inattività, quando il contenitore con il codice viene caricato e inizializzato nuovamente. Secondo la documentazione Firebase (2026), un avvio a freddo richiede da 200 ms a 2 secondi a seconda delle dimensioni del pacchetto, del numero di dipendenze e della regione. Per l'interfaccia utente, un ritardo superiore a 1 secondo è percepibile e può influire sull'esperienza dell'utente.

Modi per minimizzare l'avvio a freddo: ridurre al minimo le dipendenze, utilizzare TypeScript compilato in CommonJS, ridurre le dimensioni del pacchetto di funzioni, impostare un numero minimo di istanze attive. Firebase Cloud Functions v2 (2a generazione) consente di impostare minInstances — il numero minimo di contenitori caldi sempre pronti a elaborare le richieste. Mantenere i contenitori caldi comporta costi per il tempo di inattività.

La scalabilità di Cloud Functions avviene automaticamente: all'aumentare del volume delle richieste, Firebase crea nuovi contenitori. Per impostazione predefinita, il numero massimo di istanze parallele è 3000 (quota del progetto Google Cloud). Ogni istanza gestisce una richiesta alla volta. Se una funzione è veloce (meno di 100 ms), un'istanza può gestire fino a 10 richieste al secondo, fornendo una velocità effettiva di picco fino a 30.000 richieste al secondo per progetto.

Configurazione di minInstances e maxInstances

minInstances è un parametro che riserva un numero specifico di contenitori e li mantiene caldi. È consigliato per funzioni HTTPS critiche dove la latenza di avvio a freddo è inaccettabile. Ad esempio, per un endpoint di autenticazione, impostare minInstances: 1. maxInstances limita il numero massimo di istanze parallele, utile per prevenire una crescita incontrollata dei costi durante picchi improvvisi di traffico.

La configurazione viene effettuata nel codice: functions.runWith({ minInstances: 1, maxInstances: 10 }). Importante: minInstances aumenta i costi perché i contenitori funzionano continuamente. Per i progetti di test, minInstances dovrebbe essere disattivato. Per la produzione, minInstances è consigliato per tutte le funzioni HTTPS pubbliche e 0 per i trigger basati su eventi dove un ritardo di 1 secondo non è critico.

Regioni di distribuzione

La regione di distribuzione influisce sulla latenza per gli utenti finali e sul costo del traffico in uscita. Firebase Cloud Functions è disponibile in oltre 30 regioni Google Cloud. Per le applicazioni mobili, scegliere la regione più vicina al pubblico di destinazione: us-central1 per le Americhe, europe-west1 per l'Europa, asia-east2 per l'Asia. La regione non può essere modificata dopo la distribuzione senza ridistribuire la funzione.

Il cambio di regione viene effettuato tramite il parametro region nel codice: functions.region('europe-west1'). Tutte le funzioni in un singolo file possono avere regioni diverse. Per progetti globali, si consiglia di distribuire funzioni in più regioni e utilizzare Cloud Load Balancing per distribuire il traffico, anche se per la maggior parte delle applicazioni mobili è sufficiente una singola regione se scelta correttamente.

Esempi di codice per Firebase Cloud Functions

Vediamo degli esempi pratici di Cloud Functions in TypeScript. Il codice utilizza Firebase Functions SDK v2 (2a generazione) con sintassi dei moduli ES. Gli esempi includono la gestione di un evento di creazione utente, la generazione di una miniatura sul caricamento di un'immagine e un semplice endpoint HTTPS per un'API REST. Tutte le funzioni sono asincrone e restituiscono una Promise per la corretta terminazione del contenitore.

Prima di eseguire, assicurati che Firebase CLI sia aggiornato alla versione 13+: npm install -g firebase-tools. Le funzioni v2 richiedono il piano tariffario Blaze. Inizializzazione: firebase init functions con TypeScript selezionato.

Gestione della registrazione utente

Il primo esempio — la creazione di un documento in Firestore quando un nuovo utente si registra. La funzione viene attivata dall'evento auth.user().onCreate e scrive un profilo di base nella raccolta users/{uid}. Questo garantisce che ogni utente registrato abbia un documento con i campi necessari.

typescript
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}`)
    })

La funzione createUserProfile è asincrona — restituisce una Promise che Firebase attende prima di terminare. Se la scrittura in Firestore fallisce (ad esempio, a causa di permessi insufficienti), la funzione verrà automaticamente ritentata (se il tentativo è abilitato). Il campo role con valore “free” consente di implementare le restrizioni del piano gratuito direttamente nelle Security Rules di Firestore confrontando resource.data.role con il livello di accesso richiesto.

Generazione di miniature sul caricamento di immagini

Il secondo esempio — un trigger Storage per generare automaticamente una miniatura dopo il caricamento di un'immagine. La funzione crea una copia ridotta di 200x200 pixel e la salva nel percorso del file originale con il prefisso thumb_. L'elaborazione delle immagini utilizza la libreria sharp, che supporta tutti i formati comuni e funziona nell'ambiente Node.js senza dipendenze di sistema.

typescript
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 })
    })

La funzione generateThumbnail controlla il Content-Type dell'oggetto e ignora le non-immagini, risparmiando risorse. Per utilizzare sharp, la dipendenza deve essere aggiunta a package.json. La miniatura viene creata con il parametro fit: “cover”, che ritaglia l'immagine dal centro in un quadrato di 200x200 pixel. Dopo la creazione, la miniatura viene caricata nuovamente nello stesso bucket con un nome modificato.

Endpoint HTTPS per un'API pubblica

Il terzo esempio — una funzione HTTPS che implementa un endpoint API REST per verificare lo stato del server. La funzione accetta una richiesta GET e restituisce JSON con informazioni sullo stato dei servizi Firebase collegati al progetto. Questo endpoint è utile per il monitoraggio e per sistemi esterni che devono verificare la disponibilità del backend prima di inviare dati.

typescript
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)

La funzione api utilizza express Router per il routing, comodo quando si creano più endpoint in una singola funzione. Il controllo di salute scrive in Firestore nella raccolta _health, consentendo di verificare contemporaneamente la disponibilità di Firestore. Per la produzione, si consiglia di aggiungere l'autenticazione della richiesta tramite una chiave API o un token Firebase Auth per prevenire abusi dell'endpoint pubblico.

Casi d'uso tipici nelle applicazioni mobili

Cloud Functions sono più comunemente utilizzate per attività che non possono o non dovrebbero essere eseguite sul client: invio di notifiche push, generazione di anteprime di immagini caricate, integrazione con sistemi di pagamento esterni, moderazione dei contenuti, sincronizzazione dei dati tra Firebase e servizi di terze parti. Il modello serverless rende queste attività convenienti: si paga solo per il tempo di esecuzione effettivo del codice.

L'integrazione con sistemi di pagamento è uno scenario tipico per le app con acquisti in-app. Cloud Functions riceve un webhook dal fornitore di pagamento (Stripe, PayPal), verifica la firma della richiesta, aggiorna lo stato dell'abbonamento in Firestore e invia una conferma all'utente. Tutto il codice viene eseguito sul server senza rischio di manomissione dei dati sul client. Secondo la documentazione Stripe (2026), l'elaborazione del webhook richiede meno di 500 ms.

La moderazione intelligente dei contenuti utilizza un trigger Storage di Cloud Function per verificare automaticamente le immagini caricate tramite Google Cloud Vision API. La funzione invia l'immagine all'API Vision per rilevare contenuti non sicuri (violenza, contenuti per adulti) e, se la soglia viene superata, elimina il file e notifica l'amministratore. Questo scenario è fondamentale per le applicazioni UGC con gallerie utente.

L'aggregazione dei dati — Cloud Functions come sostituto dei contatori di Firebase Realtime Database. Invece di leggere e scrivere un contatore sul client (che porta a race condition), utilizzare un trigger onWrite di Firestore per aggiornamenti atomici di campi aggregati. Ad esempio, una funzione conta il numero di like di un post ogni volta che un documento viene aggiunto o rimosso nella sottoraccolta /posts/{postId}/likes/{userId} e aggiorna il campo likesCount nel documento padre.

Domande frequenti

Quanto tempo può funzionare una singola funzione?

Il tempo massimo di esecuzione dipende dal tipo: funzioni HTTPS — 9 minuti, trigger basati su eventi — 60 secondi (v2: fino a 60 minuti). Per operazioni di lunga durata, utilizzare Cloud Tasks o Pub/Sub con elaborazione asincrona. Il timeout è configurato nel codice tramite runWith({ timeoutSeconds: 120 }).

Come eseguire il debug di Cloud Functions localmente?

Utilizzare Firebase Emulator Suite: firebase emulators:start --only functions. L'emulatore esegue le funzioni localmente sulla porta 5001 con supporto per il ricaricamento a caldo. Per i trigger Firestore e Auth, l'emulatore sostituisce i servizi reali, consentendo di testare scenari senza rischi per i dati di produzione.

Qual è la differenza tra funzioni di 1a e 2a generazione?

La 2a generazione utilizza Google Cloud Run e Eventarc, offrendo un timeout più lungo (fino a 60 minuti), elaborazione concorrente delle richieste da parte di una singola istanza e una migliore integrazione con i servizi Google Cloud. La 1a generazione utilizza Google Cloud Functions ed è limitata a 60 secondi per le funzioni basate su eventi. Firebase consiglia di iniziare nuovi progetti con la 2a generazione.

Posso usare Python invece di JavaScript?

Firebase Cloud Functions supporta ufficialmente solo Node.js (JavaScript e TypeScript). Per Python, utilizzare Google Cloud Functions direttamente con Firebase Admin SDK per Python. Firebase Admin SDK Python supporta tutte le operazioni, ad eccezione di alcuni trigger specifici di Firebase disponibili solo tramite Node.js.

Come proteggere una funzione HTTPS da accessi non autorizzati?

Per l'accesso autenticato, verificare il token ID Firebase nell'intestazione Authorization: admin.auth().verifyIdToken(token). Per l'integrazione server-to-server, utilizzare Firebase Admin SDK con un account di servizio o chiavi API. Per gli endpoint pubblici con limitazione della velocità, utilizzare la limitazione della velocità tramite Cloud Armor o middleware.

Riepilogo

  • Firebase Cloud Functions — una piattaforma serverless per eseguire codice in risposta a eventi Firebase e richieste HTTPS.
  • Trigger supportati per Firestore, Authentication, Storage, Realtime Database, Pub/Sub e HTTPS.
  • Avvio a freddo — il principale svantaggio: fino a 2 secondi di ritardo alla prima chiamata dopo l'inattività, mitigato da minInstances.
  • Scalabilità automatica fino a 3000 istanze parallele, con pagamento per esecuzione.
  • Sviluppo in JavaScript/TypeScript con test locali tramite Firebase Emulator Suite.
  • Codice della funzione segue il modello di responsabilità singola: una funzione — un tipo di evento.
  • Sicurezza dei dati di configurazione garantita tramite functions.config() o Google Cloud Secret Manager.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche