
Installez firebase et vuefire, initialisez l’application avec initializeApp et getFirestore, puis lisez une collection avec useCollection : la liste se met à jour toute seule. Développez contre l’émulateur Firestore local plutôt que sur le projet de production.
Firebase fournit une base de données, une authentification et un hébergement sans serveur à écrire. Branché sur Vue, il donne une base temps réel dont les changements se propagent d’eux-mêmes dans l’interface. Voici comment le câbler proprement avec le SDK modulaire.
Firestore ou Realtime Database ?
Firebase propose deux bases. Realtime Database est la plus ancienne : un grand arbre JSON, des requêtes limitées. Cloud Firestore organise les données en collections de documents, propose de vraies requêtes composées et des index. Pour un projet neuf, prenez Firestore, c’est ce que fait cet article.
Installer
npm install firebase vuefireVueFire est la couche officielle qui relie Firebase à la réactivité de Vue. Elle n’est pas obligatoire, mais elle évite d’écrire à la main les abonnements et leur nettoyage.
Initialiser
Créez le projet dans la console Firebase, ajoutez une application web, et copiez la configuration. Rangez-la dans un fichier dédié :
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)Contrairement à ce que son nom suggère, elle n’est pas un secret : elle part dans le bundle JavaScript et n’importe qui peut la lire. Elle identifie le projet, elle ne l’autorise pas. La sécurité repose entièrement sur les règles Firestore et l’authentification. Écrire ses règles est la vraie tâche de sécurité, pas cacher cette clé.
Branchez ensuite VueFire sur l’application :
import { createApp } from 'vue'
import { VueFire } from 'vuefire'
import App from './App.vue'
import { firebaseApp } from './firebase'
createApp(App)
.use(VueFire, { firebaseApp })
.mount('#app')Lire une collection
useCollection renvoie une référence réactive, alimentée puis tenue à jour par 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>C’est tout : la boucle v-for affiche la collection comme n’importe quel tableau. Ouvrez la console Firebase et modifiez un document : la liste change dans le navigateur sans rechargement. VueFire ferme l’abonnement au démontage du composant, ce qui évite la fuite classique des écouteurs oubliés.
Pour un document seul, useDocument suit la même logique :
import { doc } from 'firebase/firestore'
import { useDocument } from 'vuefire'
const produit = useDocument(doc(db, 'produits', '2234'))Filtrer et trier
Les requêtes se composent avec query, where, orderBy et 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)
)
)Une requête qui combine un filtre et un tri sur des champs différents demande un index composite. Firestore refuse la requête et affiche dans la console un lien qui crée l’index en un clic, c’est le message d’erreur le plus utile du produit.
Écrire
Les écritures passent par les fonctions du SDK, pas par VueFire. Branchez-les sur un formulaire pour créer des documents depuis l’interface :
import {
addDoc, collection, deleteDoc, doc, serverTimestamp, setDoc, updateDoc
} from 'firebase/firestore'
import { db } from '@/firebase'
// identifiant généré par Firestore
await addDoc(collection(db, 'avis'), {
nom: 'Damien',
note: 5,
creeLe: serverTimestamp()
})
// identifiant choisi (crée ou remplace)
await setDoc(doc(db, 'avis', 'avis-2234'), { nom: 'Damien', note: 5 })
// modifier certains champs
await updateDoc(doc(db, 'avis', 'avis-2234'), { note: 4 })
// supprimer
await deleteDoc(doc(db, 'avis', 'avis-2234'))serverTimestamp() laisse Firestore horodater côté serveur : l’heure de la machine du visiteur n’est pas fiable.
Développer contre l’émulateur
Travailler directement sur le projet de production abîme les données et consomme le quota. La suite d’émulateurs Firebase fait tourner Firestore en local.
npm install -D firebase-tools
npx firebase init emulators # cocher Firestore
npx firebase emulators:start --only firestore --project demo-boutiqueUn identifiant de projet commençant par demo- indique à l’émulateur de fonctionner sans compte ni facturation.
Côté application, connectez le SDK à l’émulateur en développement seulement :
import { connectFirestoreEmulator, getFirestore } from 'firebase/firestore'
export const db = getFirestore(firebaseApp)
if (import.meta.env.DEV) {
connectFirestoreEmulator(db, '127.0.0.1', 8080)
}Depuis firebase-tools 15, une version antérieure du JDK fait échouer le démarrage avec le message « firebase-tools no longer supports Java version before 21 ». Vérifiez avec java -version.
Les règles de sécurité
Sans règles, la base est soit fermée, soit ouverte à tous. Le mode « test » proposé à la création expire au bout de trente jours, ne le laissez pas en production.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /avis/{avisId} {
// lecture publique
allow read: if true;
// écriture réservée aux personnes connectées, sur leur propre avis
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;
}
}
}Les règles s’écrivent et se testent aussi contre l’émulateur, ce qui évite de découvrir un trou en production.
Ce qui a changé depuis le SDK 8
Beaucoup d’exemples encore en ligne utilisent l’ancienne API à espaces de noms. Elle ne fonctionne plus telle quelle depuis Firebase 9 :
// ancien SDK (8 et avant) — ne fonctionne plus
import firebase from 'firebase'
const db = firebase.initializeApp(config).database()
db.ref('avis').push({ nom: 'Damien' })
// SDK modulaire (9 et suivants)
import { initializeApp } from 'firebase/app'
import { addDoc, collection, getFirestore } from 'firebase/firestore'
const db = getFirestore(initializeApp(config))
await addDoc(collection(db, 'avis'), { nom: 'Damien' })Le découpage en fonctions importées n’est pas cosmétique : il permet au bundler de ne garder que ce que vous utilisez. Sur une application qui ne fait que lire Firestore, la différence de poids est nette.
Côté VueFire, l’ancienne option firebase: { … } dans les composants et l’objet $firebaseRefs ont disparu : tout passe par useCollection et useDocument.
Pour aller plus loin
Ce montage suppose acquis les composants et la réactivité de Vue. Sinon, commencez par le tutoriel Vue 3 pour les débutants. Pour partager les données Firebase entre des composants éloignés, un store Pinia qui encapsule les appels Firestore est un bon patron.
Erreurs fréquentes
firebase.initializeApp(config).database() et l’objet global firebase ne fonctionnent plus depuis la version 9. Tout passe par des fonctions importées.firebase: { … } dans les composants et $firebaseRefs ont disparu : utilisez useCollection et useDocument.

