
Installeer firebase en vuefire, initialiseer de applicatie met initializeApp en getFirestore, en lees daarna een collectie met useCollection: de lijst werkt zichzelf bij. Ontwikkel tegen de lokale Firestore-emulator in plaats van tegen het productieproject.
Firebase levert een database, authenticatie en hosting zonder dat je er een server voor schrijft. Aan Vue geknoopt geeft het een realtime basis waarvan de wijzigingen zichzelf door de interface verspreiden. Zo sluit je het netjes aan met de modulaire SDK.
Firestore of Realtime Database?
Firebase biedt twee databases aan. Realtime Database is de oudste: één grote JSON-boom, met beperkte queries. Cloud Firestore ordent de data in collecties van documenten, kent echte samengestelde queries en indexen. Voor een nieuw project neem je Firestore, en dat is wat dit artikel doet.
Installeren
npm install firebase vuefireVueFire is de officiële laag die Firebase aan de reactiviteit van Vue koppelt. Verplicht is het niet, maar het scheelt je het handwerk van abonnementen opzetten en weer opruimen.
Initialiseren
Maak het project aan in de Firebase-console, voeg een webapplicatie toe en kopieer de configuratie. Zet die in een eigen bestand:
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)Anders dan de naam suggereert is het geen geheim: hij gaat mee in de JavaScript-bundle en iedereen kan hem lezen. Hij identificeert het project, hij geeft er geen toegang toe. De beveiliging zit volledig in de Firestore-rules en de authenticatie. Je rules schrijven is het echte beveiligingswerk, niet die sleutel verstoppen.
Sluit VueFire daarna aan op de applicatie:
import { createApp } from 'vue'
import { VueFire } from 'vuefire'
import App from './App.vue'
import { firebaseApp } from './firebase'
createApp(App)
.use(VueFire, { firebaseApp })
.mount('#app')Een collectie lezen
useCollection geeft een reactieve ref terug, die Firestore vult en daarna bijhoudt:
<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>Meer is het niet: de v-for-lus toont de collectie als een gewone array. Open de Firebase-console en pas een document aan: de lijst verandert in de browser zonder herladen. VueFire sluit het abonnement wanneer de component wordt afgebroken, wat het klassieke lek van vergeten listeners voorkomt.
Voor één enkel document volgt useDocument dezelfde logica:
import { doc } from 'firebase/firestore'
import { useDocument } from 'vuefire'
const produit = useDocument(doc(db, 'produits', '2234'))Filteren en sorteren
Queries stel je samen met query, where, orderBy en 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)
)
)Een query die een filter en een sortering op verschillende velden combineert, vraagt om een composite index. Firestore weigert de query en zet in de console een link die de index met één klik aanmaakt, het nuttigste foutbericht van het hele product.
Schrijven
Schrijfacties lopen via de functies van de SDK, niet via VueFire. Hang ze aan een formulier om documenten vanuit de interface aan te maken:
import {
addDoc, collection, deleteDoc, doc, serverTimestamp, setDoc, updateDoc
} from 'firebase/firestore'
import { db } from '@/firebase'
// door Firestore gegenereerde id
await addDoc(collection(db, 'avis'), {
nom: 'Damien',
note: 5,
creeLe: serverTimestamp()
})
// zelfgekozen id (maakt aan of vervangt)
await setDoc(doc(db, 'avis', 'avis-2234'), { nom: 'Damien', note: 5 })
// enkele velden aanpassen
await updateDoc(doc(db, 'avis', 'avis-2234'), { note: 4 })
// verwijderen
await deleteDoc(doc(db, 'avis', 'avis-2234'))serverTimestamp() laat Firestore de tijdstempel aan de serverkant zetten: de klok van de machine van de bezoeker is niet betrouwbaar.
Ontwikkelen tegen de emulator
Rechtstreeks op het productieproject werken beschadigt je data en vreet quotum. De Firebase-emulatorsuite draait Firestore lokaal.
npm install -D firebase-tools
npx firebase init emulators # Firestore aanvinken
npx firebase emulators:start --only firestore --project demo-boutiqueEen project-id die met demo- begint, vertelt de emulator dat hij zonder account en zonder facturering moet werken.
Sluit de SDK aan de applicatiekant alleen in ontwikkeling op de emulator aan:
import { connectFirestoreEmulator, getFirestore } from 'firebase/firestore'
export const db = getFirestore(firebaseApp)
if (import.meta.env.DEV) {
connectFirestoreEmulator(db, '127.0.0.1', 8080)
}Sinds firebase-tools 15 laat een oudere JDK het opstarten mislukken met de melding “firebase-tools no longer supports Java version before 21”. Controleer dat met java -version.
De securityrules
Zonder rules is de database ofwel dicht, ofwel open voor iedereen. De testmodus die bij het aanmaken wordt voorgesteld, verloopt na dertig dagen, laat die niet in productie staan.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /avis/{avisId} {
// publiek leesbaar
allow read: if true;
// schrijven alleen voor ingelogde personen, op hun eigen review
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;
}
}
}Rules schrijf en test je ook tegen de emulator, zodat je een gat niet pas in productie ontdekt.
Wat er sinds SDK 8 veranderd is
Veel voorbeelden die nog online staan, gebruiken de oude API met namespaces. Die werkt sinds Firebase 9 niet meer zoals hij is:
// oude SDK (8 en eerder) — werkt niet meer
import firebase from 'firebase'
const db = firebase.initializeApp(config).database()
db.ref('avis').push({ nom: 'Damien' })
// modulaire SDK (9 en later)
import { initializeApp } from 'firebase/app'
import { addDoc, collection, getFirestore } from 'firebase/firestore'
const db = getFirestore(initializeApp(config))
await addDoc(collection(db, 'avis'), { nom: 'Damien' })De opsplitsing in geïmporteerde functies is niet cosmetisch: de bundler kan daardoor alleen bewaren wat je echt gebruikt. Bij een applicatie die niets anders doet dan Firestore uitlezen, scheelt dat merkbaar in gewicht.
Aan de VueFire-kant zijn de oude optie firebase: { … } in componenten en het object $firebaseRefs verdwenen: alles loopt via useCollection en useDocument.
Verder gaan
Deze opzet gaat ervan uit dat je de componenten en de reactiviteit van Vue al kent. Zo niet, begin dan bij de Vue 3-tutorial voor beginners. Om Firebase-data te delen tussen componenten die ver uit elkaar liggen, is een Pinia-store die de Firestore-aanroepen inkapselt een goed patroon.
Veelgemaakte fouten
firebase.initializeApp(config).database() en het globale object firebase werken sinds versie 9 niet meer. Alles loopt via geïmporteerde functies.firebase: { … } in componenten en $firebaseRefs zijn verdwenen: gebruik useCollection en useDocument.

