
Installa firebase e vuefire, inizializza l'applicazione con initializeApp e getFirestore, poi leggi una collezione con useCollection: la lista si aggiorna da sola. Sviluppa sull'emulatore Firestore locale invece che sul progetto di produzione.
Firebase offre un database, un’autenticazione e un hosting senza righe di server da scrivere. Collegato a Vue, dà una base in tempo reale le cui modifiche si propagano da sole nell’interfaccia. Ecco come cablarlo per bene con l’SDK modulare.
Firestore o Realtime Database?
Firebase propone due database. Realtime Database è il più vecchio: un grande albero JSON, query limitate. Cloud Firestore organizza i dati in collezioni di documenti, offre vere query composte e degli indici. Per un progetto nuovo scegli Firestore, ed è quello che fa questo articolo.
Installare
npm install firebase vuefireVueFire è il livello ufficiale che collega Firebase alla reattività di Vue. Non è obbligatorio, ma evita di scrivere a mano le sottoscrizioni e la loro pulizia.
Inizializzare
Crea il progetto nella console Firebase, aggiungi un’applicazione web e copia la configurazione. Mettila in un file dedicato:
import { initializeApp } from 'firebase/app'
import { getFirestore } from 'firebase/firestore'
export const firebaseApp = initializeApp({
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
authDomain: 'mon-projet.firebaseapp.com',
projectId: 'mon-projet'
})
export const db = getFirestore(firebaseApp)Al contrario di quanto suggerisce il nome, non è un segreto: finisce nel bundle JavaScript e chiunque può leggerla. Identifica il progetto, non lo autorizza. La sicurezza dipende interamente dalle regole Firestore e dall’autenticazione. Scrivere le proprie regole è il vero lavoro di sicurezza, non nascondere questa chiave.
Collega poi VueFire all’applicazione:
import { createApp } from 'vue'
import { VueFire } from 'vuefire'
import App from './App.vue'
import { firebaseApp } from './firebase'
createApp(App)
.use(VueFire, { firebaseApp })
.mount('#app')Leggere una collezione
useCollection restituisce un riferimento reattivo, popolato e poi tenuto aggiornato da Firestore:
<script setup>
import { collection } from 'firebase/firestore'
import { useCollection } from 'vuefire'
import { db } from '@/firebase'
const avis = useCollection(collection(db, 'avis'))
</script>
<template>
<ul>
<li v-for="a in avis" :key="a.id">{{ a.nom }} : {{ a.note }}/5</li>
</ul>
</template>Tutto qui: il ciclo v-for mostra la collezione come qualsiasi altro array. Apri la console Firebase e modifica un documento: la lista cambia nel browser senza ricaricare la pagina. VueFire chiude la sottoscrizione allo smontaggio del componente, il che evita la classica perdita dei listener dimenticati.
Per un solo documento, useDocument segue la stessa logica:
import { doc } from 'firebase/firestore'
import { useDocument } from 'vuefire'
const produit = useDocument(doc(db, 'produits', '2234'))Filtrare e ordinare
Le query si compongono con query, where, orderBy e limit:
import { collection, limit, orderBy, query, where } from 'firebase/firestore'
const meilleursAvis = useCollection(
query(
collection(db, 'avis'),
where('note', '>=', 4),
orderBy('note', 'desc'),
limit(10)
)
)Una query che combina un filtro e un ordinamento su campi diversi richiede un indice composito. Firestore la rifiuta e mostra nella console un link che crea l’indice con un clic: è il messaggio di errore più utile del prodotto.
Scrivere
Le scritture passano dalle funzioni dell’SDK, non da VueFire. Collegale a un form per creare documenti dall’interfaccia:
import {
addDoc, collection, deleteDoc, doc, serverTimestamp, setDoc, updateDoc
} from 'firebase/firestore'
import { db } from '@/firebase'
// identificatore generato da Firestore
await addDoc(collection(db, 'avis'), {
nom: 'Damien',
note: 5,
creeLe: serverTimestamp()
})
// identificatore scelto (crea o sostituisce)
await setDoc(doc(db, 'avis', 'avis-2234'), { nom: 'Damien', note: 5 })
// modificare alcuni campi
await updateDoc(doc(db, 'avis', 'avis-2234'), { note: 4 })
// eliminare
await deleteDoc(doc(db, 'avis', 'avis-2234'))serverTimestamp() lascia a Firestore il compito di mettere la data lato server: l’orologio della macchina del visitatore non è affidabile.
Sviluppare sull’emulatore
Lavorare direttamente sul progetto di produzione rovina i dati e consuma la quota. La suite di emulatori Firebase fa girare Firestore in locale.
npm install -D firebase-tools
npx firebase init emulators # spuntare Firestore
npx firebase emulators:start --only firestore --project demo-boutiqueUn identificatore di progetto che comincia per demo- dice all’emulatore di funzionare senza account né fatturazione.
Lato applicazione, collega l’SDK all’emulatore solo in sviluppo:
import { connectFirestoreEmulator, getFirestore } from 'firebase/firestore'
export const db = getFirestore(firebaseApp)
if (import.meta.env.DEV) {
connectFirestoreEmulator(db, '127.0.0.1', 8080)
}Da firebase-tools 15, una versione precedente del JDK fa fallire l’avvio con il messaggio « firebase-tools no longer supports Java version before 21 ». Controlla con java -version.
Le regole di sicurezza
Senza regole, il database è o chiuso o aperto a tutti. La modalità « test » proposta alla creazione scade dopo trenta giorni, non lasciarla in produzione.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /avis/{avisId} {
// lettura pubblica
allow read: if true;
// scrittura riservata alle persone autenticate, sulla propria recensione
allow create: if request.auth != null
&& request.resource.data.auteurId == request.auth.uid;
allow update, delete: if request.auth != null
&& resource.data.auteurId == request.auth.uid;
}
}
}Anche le regole si scrivono e si testano sull’emulatore, il che evita di scoprire un buco in produzione.
Che cosa è cambiato dall’SDK 8
Molti esempi ancora online usano la vecchia API a namespace. Dalla versione 9 di Firebase non funziona più così com’è:
// SDK vecchio (8 e precedenti) — non funziona più
import firebase from 'firebase'
const db = firebase.initializeApp(config).database()
db.ref('avis').push({ nom: 'Damien' })
// SDK modulare (9 e successivi)
import { initializeApp } from 'firebase/app'
import { addDoc, collection, getFirestore } from 'firebase/firestore'
const db = getFirestore(initializeApp(config))
await addDoc(collection(db, 'avis'), { nom: 'Damien' })La suddivisione in funzioni importate non è cosmetica: permette al bundler di tenere solo quello che usi davvero. Su un’applicazione che si limita a leggere Firestore, la differenza di peso si vede.
Lato VueFire, la vecchia opzione firebase: { … } nei componenti e l’oggetto $firebaseRefs sono spariti: tutto passa da useCollection e useDocument.
Per approfondire
Questo montaggio dà per acquisiti i componenti e la reattività di Vue. Altrimenti comincia dal tutorial Vue 3 per principianti. Per condividere i dati Firebase tra componenti lontani fra loro, uno store Pinia che incapsula le chiamate Firestore è un buon schema.
Errori frequenti
firebase.initializeApp(config).database() e l'oggetto globale firebase non funzionano più dalla versione 9. Tutto passa da funzioni importate.firebase: { … } nei componenti e $firebaseRefs sono spariti: usa useCollection e useDocument.

