Firebase Storage: cos'è, upload di file e archiviazione nel cloud

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

Firebase Storage è un servizio di archiviazione file nel cloud che fa parte dell'ecosistema Firebase di Google, progettato per caricare e scaricare immagini, video, audio e altri dati binari da applicazioni mobili e web. A differenza di un disco cloud normale, Storage si integra con Firebase Authentication e Security Rules, consentendo un controllo flessibile dell'accesso a ogni file a livello di richiesta. Secondo Google Firebase (2026), il servizio elabora oltre 500 milioni di operazioni sui file ogni giorno, fornendo archiviazione scalabile senza la necessità di gestire infrastrutture server.

Punti chiave

  • Firebase Storage — un archivio cloud per i file delle applicazioni integrato con la piattaforma Firebase.
  • L'upload viene eseguito direttamente dal client tramite SDK, bypassando il proprio server.
  • Le regole di sicurezza consentono di controllare l'accesso a ogni file in base all'autenticazione e al contenuto.
  • La resilienza alle interruzioni di connessione è garantita dall'upload riprendibile automatico dal punto di interruzione.
  • L'integrazione con Cloud Functions consente di elaborare i file dopo l'upload.

Cos'è Firebase Storage e come funziona

Firebase Storage è un archivio di oggetti nel cloud costruito su Google Cloud Storage che fornisce SDK per Android, iOS e piattaforme web. Ogni file viene archiviato come oggetto in un bucket di Google Cloud e viene indirizzato da un percorso simile a un filesystem: gs://bucket-name/path/to/file.jpg. Un singolo file può raggiungere i 5 TB, consentendo di archiviare qualsiasi dato multimediale senza compressione preliminare.

L'architettura di Firebase Storage utilizza un modello di riferimento dei link (gsutil references) anziché una gerarchia di cartelle classica, sebbene l'SDK fornisca un'interfaccia con directory per comodità dello sviluppatore. Fisicamente, tutti gli oggetti sono archiviati nello spazio dei nomi piatto del bucket e le cartelle virtuali vengono create utilizzando prefissi di percorso. Ciò garantisce prestazioni di ricerca lineari indipendentemente dal numero di file.

Il vantaggio principale di Firebase Storage rispetto all'uso diretto di Google Cloud Storage è l'integrazione incorporata con Firebase Authentication e Security Rules. Lo sviluppatore non ha bisogno di configurare ruoli IAM e account di servizio separati: le regole di accesso sono scritte in un linguaggio dichiarativo simile a Firebase Realtime Database Rules e vengono applicate automaticamente a ogni richiesta.

Struttura del bucket e percorsi dei file

Un bucket di Firebase Storage viene creato automaticamente quando si abilita il servizio nella console Firebase. Il percorso del file segue il modello /nome_cartella/nome_file e può contenere livelli annidati. Si consiglia di organizzare i percorsi secondo lo schema /users/{userId}/images/{imageId}.jpg per isolare i dati tra gli utenti. Questa struttura semplifica la scrittura delle regole di sicurezza poiché il percorso contiene l'identificatore del proprietario.

È importante capire che Firebase Storage non è un database relazionale o un file server nel senso classico. È un archivio di oggetti ottimizzato per operazioni di lettura e scrittura di file interi. L'aggiornamento parziale di un file non è possibile: se si ricarica allo stesso percorso, l'oggetto vecchio viene sostituito dal nuovo. Per archiviare piccoli dati strutturati, utilizza Firebase Realtime Database o Cloud Firestore.

Prezzi e limiti di Firebase Storage

Il prezzo di Firebase Storage dipende dalla quantità di dati archiviati e dal numero di operazioni. Il piano gratuito (Spark) include 5 GB di archiviazione, 20.000 operazioni di scrittura e 50.000 operazioni di lettura al giorno. Il piano a pagamento (Blaze) addebita in base all'uso effettivo: $0,026 per GB di dati archiviati, $0,05 per 10.000 operazioni di scrittura e $0,004 per 10.000 operazioni di lettura. Sono previsti costi aggiuntivi per il traffico in uscita.

Per la maggior parte delle applicazioni mobili con poche migliaia di utenti, il limite gratuito è sufficiente durante la fase di prototipazione e test. Quando si scala a centinaia di migliaia di utenti, i costi di Storage raramente superano i $50–$100 al mese con un approccio di upload ottimizzato e caching lato client.

Come caricare file in Firebase Storage

Caricare un file in Firebase Storage viene eseguito tramite il metodo SDK appropriato, che accetta un percorso di archiviazione e i dati del file (array di byte, URI, flusso o Bitmap). L'SDK gestisce automaticamente la connessione, segmenta il file in parti per dimensioni grandi e fornisce callback per il monitoraggio del progresso. L'upload viene eseguito direttamente dal dispositivo client a Google Cloud, bypassando il tuo server, riducendo il carico sulla tua infrastruttura.

Per Android, l'SDK di Firebase Storage utilizza le classi StorageReference e UploadTask. Una StorageReference viene creata dal percorso root tramite Firebase.storage.reference e punta a un file specifico nel bucket. UploadTask restituisce listener per progresso, pausa e completamento. Quando una connessione viene interrotta, UploadTask riprende automaticamente l'upload dall'ultimo byte trasmesso con successo — questo comportamento è chiamato upload riprendibile.

I metadati del file (Content-Type, campi personalizzati) vengono passati come un oggetto SettableMetadata separato all'avvio dell'upload. Impostare correttamente il Content-Type è fondamentale per la corretta visualizzazione dei file nel browser e per il caching CDN. Firebase Storage supporta tutti i tipi MIME standard: image/jpeg, image/png, video/mp4, application/pdf e altri.

Gestione dei metadati durante l'upload

I metadati del file contengono campi di sistema (Content-Type, Cache-Control, Content-Disposition) e coppie chiave-valore personalizzate (customMetadata). I campi di sistema controllano le intestazioni HTTP durante il download. Ad esempio, Cache-Control: public, max-age=31536000 abilita il caching della risposta per un anno, riducendo significativamente i download ripetuti dello stesso file e risparmiando traffico.

I metadati personalizzati sono utili per passare informazioni aggiuntive su un file senza creare una raccolta separata in Firestore. Ad esempio, il campo uploadedBy può memorizzare l'userId dell'utente che ha caricato il file, semplificando l'implementazione di gallerie con contenuti generati dagli utenti. I metadati personalizzati non sono protetti separatamente da Security Rules — il loro accesso è regolato dalle stesse regole del file stesso.

Upload multipli ed elaborazione batch

Quando è necessario caricare più file contemporaneamente (ad esempio, foto da una galleria), non è consigliabile eseguire UploadTask indipendenti in parallelo senza limiti. Sui dispositivi mobili, upload paralleli di più di 3–5 file sovraccaricano lo stack di rete e causano timeout. La strategia ottimale è utilizzare un limite di concorrenza di 3 o un upload sequenziale con una barra di progresso condivisa.

Per l'elaborazione lato server dopo l'upload (generazione di miniature, compressione, moderazione dei contenuti), utilizza il trigger di Firebase Cloud Functions: functions.storage.object().onFinalize(). Questa funzione viene chiamata automaticamente dopo il completamento di ogni upload di file e può salvare una copia elaborata in un percorso diverso. Maggiori dettagli nella sezione dei casi d'uso tipici.

Scaricare file e gestire i link

Firebase Storage supporta due metodi di download: download diretto tramite SDK (ottenendo un array di byte o un file locale) e ottenimento di un URL di download diretto per l'accesso HTTP. L'URL diretto può essere utilizzato per visualizzare immagini in ImageView, in WebView o per fornire un link all'utente. L'URL di download viene generato con un token di sicurezza che può essere revocato nella console Firebase.

Il metodo storageReference.downloadUrl restituisce un URL nel formato https://firebasestorage.googleapis.com/v0/b/{bucket}/o/{path}?alt=media&token={token}. Il token di sicurezza viene automaticamente incluso nell'URL durante la generazione, quindi il link può essere condiviso con terze parti (ad esempio, in un messenger) senza rischio di accesso non autorizzato. Tuttavia, se il token viene compromesso, può essere revocato tramite la console Firebase nella sezione Storage — dopo di che, tutti i link con questo token smetteranno di funzionare.

Per il caching dei file scaricati sul client, utilizza l'archiviazione locale con il meccanismo ETag o hash MD5. Firebase Storage restituisce un'intestazione HTTP ETag quando richiede un file, che può essere confrontata con un valore archiviato localmente per evitare di scaricare nuovamente file invariati. Questo è particolarmente utile per i contenuti multimediali: avatar, immagini di copertina, anteprime — file che vengono raramente aggiornati ma spesso richiesti.

URL di download diretti e loro sicurezza

Un URL di download con un token è il modo principale per fornire accesso ai file agli utenti non autenticati (ad esempio, per visualizzare un'immagine in un feed di notizie). Il token viene generato una volta e non cambia fino alla revoca, quindi l'URL può essere memorizzato in un database (ad esempio, accanto al campo avatarUrl in Firestore). Quando l'avatar viene cambiato, il vecchio file viene eliminato e un nuovo URL viene generato e salvato.

È importante ricordare: avere un URL di download non annulla le Security Rules. Se una regola nega la lettura del file, il metodo downloadUrl restituirà un errore di Autorizzazione Negata. Ciò significa che anche conoscendo il percorso corretto del file, un client non autenticato non può ottenere il link. Una volta ottenuto, l'URL fornisce accesso HTTP bypassando le Security Rules — quindi il token è l'unica protezione del link di download.

Caching e lavoro con ETag

HTTP ETag è un identificatore di versione del file che cambia ogni volta che il contenuto viene modificato. Firebase Storage restituisce automaticamente un ETag nella risposta GET. L'applicazione client può memorizzare l'ETag in una cache locale e inviare l'intestazione If-None-Match: {etag} nelle richieste successive. Se il file non è cambiato, il server restituisce uno stato 304 Non Modificato senza trasmettere dati.

Per implementare caching intelligente in un'applicazione mobile, utilizza una combinazione del filesystem locale e di un database (ad esempio, Room per memorizzare le coppie percorso-ETag). Durante il caricamento di un file, controlla l'ETag dal database: se corrisponde a quello del server, usa la copia locale. Questo approccio riduce il traffico del 60–80% per i file multimediali statici e accelera il caricamento delle schermate con gallerie.

Regole di sicurezza per Firebase Storage

Security Rules è un linguaggio dichiarativo di controllo degli accessi per i file in Firebase Storage, eseguito lato server Firebase. Ogni regola è legata a un percorso del bucket e definisce le condizioni in cui un'operazione di lettura o scrittura è consentita. Le regole vengono verificate prima di ogni richiesta e non possono essere aggirate dal codice client. Questa è l'unica linea di difesa dei dati contro l'accesso non autorizzato.

La regola di base è accesso solo per utenti autenticati: allow read, write: if request.auth != null. Questa regola garantisce che solo gli utenti che hanno effettuato l'accesso possano leggere e scrivere file. Per una configurazione più fine, viene utilizzata la variabile request.auth.uid, che contiene l'identificatore dell'utente corrente. Confrontando l'uid con una parte del percorso del file, puoi creare un archivio isolato per ogni utente.

Importante: Security Rules non sono un meccanismo di convalida dei contenuti. Se devi verificare il tipo di file, la dimensione o la presenza di codice dannoso, utilizza la regola request.resource, che contiene i metadati del file caricato. Le proprietà disponibili sono request.resource.size (dimensione del file), request.resource.contentType (tipo MIME) e request.resource.md5Hash (checksum). Tuttavia, la convalida completa del contenuto viene eseguita lato server tramite Cloud Functions.

ScenarioRegola Security Rules
Solo autenticatiallow read, write: if request.auth != null
Solo proprietarioallow write: if request.auth.uid == userId
Lettura pubblicaallow read: if true; allow write: if request.auth != null
Limite di dimensioneallow write: if request.resource.size < 5 * 1024 * 1024
Limite di tipoallow write: if request.resource.contentType.startsWith('image/')

Esempio di regole per contenuti generati dagli utenti

Una configurazione tipica per un'applicazione con avatar utente e una galleria è la seguente. L'utente può solo scrivere nella propria directory /users/{userId}/, ma può leggere qualsiasi file in questa directory (galleria pubblica). La dimensione del file è limitata a 5 MB e il tipo è limitato alle sole immagini. Questa combinazione di regole copre l'80% dei casi d'uso di Firebase Storage nelle applicazioni social e UGC.

Suggerimento per la sicurezza: non utilizzare mai la regola allow read, write: if true per l'intero bucket. Questo apre l'accesso in scrittura a chiunque conosca il tuo projectId. Nel 2025, gli attacchi ai bucket Firebase non protetti sono aumentati, con gli aggressori che utilizzano l'accesso aperto per archiviare contenuti illegali. Inizia sempre con le autorizzazioni minime necessarie ed espandile solo quando esplicitamente necessario.

Convalida dei contenuti tramite Cloud Functions

Il trigger di Cloud Functions functions.storage.object().onFinalize() consente di eseguire la convalida del contenuto dopo l'upload. Se il file non supera la convalida (ad esempio, contiene un virus o viola le regole della piattaforma), la funzione può eliminarlo e notificare l'utente. Questo è l'unico modo per verificare il contenuto effettivo, poiché Security Rules vede solo i metadati (dimensione e tipo MIME), non i dati binari.

Esempio di convalida: una funzione Node.js scarica il file caricato in una directory temporanea, lo esegue attraverso un rilevatore antivirus (ad esempio, ClamAV) e, se viene trovata una minaccia, elimina il file e registra l'evento in Firebase Crashlytics. Il tempo di esecuzione della funzione è limitato a 540 secondi, sufficiente per verificare file fino a 50 MB.

Esempi di codice per Firebase Storage in Kotlin

Vediamo esempi pratici di integrazione di Firebase Storage in un'applicazione Android utilizzando Kotlin. Il codice utilizza classi standard dell'SDK Firebase e dimostra il caricamento di un'immagine dalla galleria del dispositivo, il download di un file con monitoraggio del progresso e l'ottenimento di un URL di download. Tutti gli esempi includono la gestione degli errori e la sospensione delle attività in caso di perdita di connessione.

Prima di utilizzare il codice, assicurati che il file build.gradle includa la dipendenza implementation(platform("com.google.firebase:firebase-bom:33.0.0")) e implementation("com.google.firebase:firebase-storage"). Firebase BOM seleziona automaticamente le versioni compatibili di tutti gli SDK, eliminando i conflitti di versione.

Caricamento di un'immagine dalla galleria

Il primo esempio dimostra il caricamento di un file selezionato dall'utente tramite Intent ACTION_GET_CONTENT. L'URI del file ottenuto viene passato all'SDK di Firebase Storage, che legge i dati da questo URI. Il metodo putFile accetta un URI e restituisce un UploadTask — un oggetto attraverso il quale puoi monitorare il progresso, mettere in pausa e riprendere l'upload.

kotlin
val storageRef = Firebase.storage.reference
val imageRef = storageRef.child(
    "users/${auth.uid}/profile.jpg"
)

val metadata = SettableMetadata().apply {
    contentType = "image/jpeg"
    customMetadata = mapOf(
        "uploadedBy" to auth.uid!!
    )
}

imageRef.putFile(imageUri, metadata)
    .addOnSuccessListener {
        Log.d("Storage", "File caricato")
    }
    .addOnFailureListener { e ->
        Log.e("Storage", "Errore: ${e.message}")
    }

Nell'esempio sopra, la variabile storageRef è il riferimento radice al bucket del progetto. Il metodo child accetta una stringa di percorso e restituisce una StorageReference che punta a un file specifico. Se un file nel percorso specificato esiste già, verrà sovrascritto. I metadati contentType e customMetadata vengono passati tramite l'oggetto SettableMetadata, che è allegato alla richiesta putFile.

Download di un file con progresso

Il secondo esempio dimostra il download di un file ottenendo un array di byte per la visualizzazione in un ImageView. Il metodo getBytes(maxSize) carica l'intero file in memoria. Per file più grandi di 10 MB, utilizza getFile(localUri) — salva il contenuto direttamente in un file locale senza archiviarlo nella RAM, prevenendo OutOfMemoryError.

kotlin
val islandRef = storageRef.child("images/island.jpg")

val ONE_MEGABYTE: Long = 1024 * 1024
islandRef.getBytes(ONE_MEGABYTE)
    .addOnSuccessListener { bytes ->
        imageView.setImageBitmap(
            BitmapFactory.decodeByteArray(
                bytes, 0, bytes.size
            )
        )
    }
    .addOnFailureListener { e ->
        Log.e("Storage", "Caricamento fallito: ${e.message}")
    }

Per ottenere un URL di download (ad esempio, per salvare il link in Firestore), utilizza il metodo downloadUrl:

kotlin
islandRef.downloadUrl.addOnSuccessListener { uri ->
    Log.d("Storage", "URL di download: $uri")
    // Salva uri.toString() in Firestore
}

Suggerimento: l'URL di download viene generato una volta e rimane stabile fino alla revoca. Salvalo nel database al primo upload invece di richiederlo ogni volta che visualizzi il file. Questo riduce il numero di richieste a Firebase Storage e migliora le prestazioni dell'interfaccia utente.

Casi d'uso tipici di Firebase Storage

Firebase Storage viene utilizzato nelle applicazioni mobili per archiviare qualsiasi file utente e di sistema. Gli scenari più comuni includono avatar e foto del profilo, immagini nei feed di contenuti, file video e audio, documenti (PDF, DOCX) per la condivisione tra utenti e backup di dati su piccola scala. In tutti questi casi, Storage funge da archivio file specializzato in combinazione con Firestore per memorizzare metadati e link.

Le applicazioni social sono il caso d'uso più comune. Ogni utente carica un avatar, foto dei post e file multimediali. La struttura dei percorsi /users/{uid}/posts/{postId}/image.jpg isola i dati e semplifica le Security Rules. Quando un utente viene eliminato, una Cloud Function può attraversare tutte le directory dell'utente e pulire l'archivio. Secondo il blog di Firebase (2025), questo modello viene utilizzato nel 70% dei progetti Firebase in produzione.

Le applicazioni di e-commerce utilizzano Firebase Storage per archiviare foto dei prodotti, cataloghi e file PDF con istruzioni. In questo caso, l'accesso ai file è solitamente pubblico (lettura senza autenticazione), mentre la scrittura è limitata agli amministratori tramite Cloud Functions con verifica dei permessi. Gli URL di download dei prodotti vengono archiviati in Firestore insieme agli altri dati del prodotto, consentendo di visualizzare le immagini senza richieste aggiuntive a Storage.

Messenger e chat archiviano immagini e messaggi vocali inviati nelle conversazioni in Firebase Storage. Il percorso è strutturato come /chats/{chatId}/messages/{messageId}.jpg. L'accesso in lettura è limitato ai partecipanti alla chat, verificato tramite Security Rules utilizzando i dati di Firestore. Questo è uno dei pochi scenari in cui una regola legge dati da un altro servizio Firebase: allow read: if firestore.exists(/databases/(default)/documents/chats/{chatId}/members/{request.auth.uid}).

Domande frequenti

In cosa differisce Firebase Storage da Google Cloud Storage?

Firebase Storage è un overlay su Google Cloud Storage con integrazione di Firebase Authentication e Security Rules. Lo sviluppatore non ha bisogno di configurare ruoli IAM e account di servizio. Google Cloud Storage offre capacità più ampie (notifiche Pub/Sub, Object Lifecycle Management) ma richiede una gestione manuale degli accessi tramite GCP IAM.

Come limitare la dimensione di un file caricato?

Il limite di dimensione viene impostato nelle Security Rules tramite request.resource.size. Esempio: allow write: if request.resource.size <= 5 * 1024 * 1024 limita i file a 5 MB. Inoltre, puoi verificare lato client prima dell'invio per non sprecare il traffico dell'utente su file chiaramente non validi.

Si può eliminare un file usando l'SDK di Firebase Storage?

Sì, l'eliminazione viene eseguita utilizzando il metodo delete() dell'oggetto StorageReference: storageRef.child("path").delete(). L'operazione di eliminazione è irreversibile e rimuove il file dal bucket immediatamente. Un file può essere eliminato solo se Security Rules consente la scrittura per il percorso specificato. Dopo l'eliminazione, l'URL di download smette di funzionare.

Come rendere l'archivio di sola lettura?

Nelle Security Rules, consenti la lettura a tutti (o utenti autenticati) e nega la scrittura: allow read: if request.auth != null; allow write: if false. La scrittura in questa modalità è possibile solo tramite l'account di servizio Firebase Admin SDK — ad esempio, da Cloud Functions con privilegi amministrativi. Questo è il modello standard per cataloghi di prodotti e contenuti pubblici.

Come gestisce Firebase Storage le interruzioni di connessione durante l'upload?

UploadTask utilizza il protocollo di upload riprendibile basato su HTTP PUT con segmentazione. Quando una connessione viene interrotta, l'upload riprende dall'ultimo byte confermato, non dall'inizio. Non è richiesta alcuna configurazione aggiuntiva per questo comportamento — l'SDK lo fa automaticamente per i file più grandi di 1 MB.

Riepilogo

  • Firebase Storage è un archivio di oggetti cloud basato su Google Cloud Storage con integrazione Firebase Authentication e Security Rules.
  • L'upload di file viene eseguito direttamente dal client tramite SDK con supporto per upload riprendibile in caso di interruzioni di connessione.
  • Il download è possibile tramite SDK (array di byte o file locale) o tramite URL di download diretto con token di sicurezza.
  • Security Rules sono l'unico meccanismo di protezione dei dati, consentendo il controllo degli accessi per percorso, autenticazione, dimensione e tipo di file.
  • Il caching tramite HTTP ETag riduce il traffico del 60–80% per i file multimediali statici se implementato correttamente sul client.
  • Il trigger onFinalize di Cloud Functions consente la post-elaborazione dei file: compressione, moderazione, generazione di anteprime.
  • I prezzi sono prevedibili: il limite gratuito di 5 GB copre i prototipi e il piano Blaze pay-as-you-go addebita in base all'uso effettivo.

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