Firebase in Vue 3 einbinden: Firestore mit VueFire nutzen

Firebase ist einer der einfachsten Wege zu einer gehosteten Echtzeitdatenbank. VueFire macht es noch bequemer: Es bildet die Firebase-Objekte direkt ab und hält sie über das Reaktivitätssystem von Vue aktuell. Zusammen ergibt das ein wunderbar einfaches Ergebnis

Firebase in Vue 3 einbinden: Firestore mit VueFire nutzen
Schnelle Antwort

Installiere firebase und vuefire, initialisiere die Anwendung mit initializeApp und getFirestore und lies eine Sammlung dann mit useCollection: Die Liste aktualisiert sich von selbst. Entwickle gegen den lokalen Firestore-Emulator statt gegen das Produktionsprojekt.

Firebase liefert Datenbank, Authentifizierung und Hosting, ohne dass du dafür Server-Code schreibst. An Vue angeschlossen, ergibt das eine Echtzeitdatenbank, deren Änderungen von selbst in der Oberfläche ankommen. So verkabelst du beides sauber mit dem modularen SDK.

Firestore oder Realtime Database?

Firebase bietet zwei Datenbanken an. Realtime Database ist die ältere: ein großer JSON-Baum mit begrenzten Abfragen. Cloud Firestore organisiert die Daten in Sammlungen von Dokumenten, kennt echte zusammengesetzte Abfragen und Indizes. Für ein neues Projekt nimmst du Firestore, genau das macht dieser Artikel.

Installieren

bash
npm install firebase vuefire

VueFire ist die offizielle Schicht, die Firebase an die Reaktivität von Vue anbindet. Pflicht ist sie nicht, aber sie erspart dir, die Abonnements und ihr Aufräumen von Hand zu schreiben.

Initialisieren

Leg das Projekt in der Firebase-Konsole an, füge eine Web-App hinzu und kopiere die Konfiguration. Sie gehört in eine eigene Datei:

src/firebase/index.js
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)
Der Firebase-API-Schlüssel ist öffentlich

Anders als der Name nahelegt, ist er kein Geheimnis: Er landet im JavaScript-Bundle und jeder kann ihn lesen. Er identifiziert das Projekt, er autorisiert es nicht. Die Sicherheit hängt vollständig an den Firestore-Regeln und der Authentifizierung. Diese Regeln zu schreiben ist die eigentliche Sicherheitsarbeit, nicht das Verstecken des Schlüssels.

Danach hängst du VueFire an die Anwendung:

src/main.js
import { createApp } from 'vue'
import { VueFire } from 'vuefire'
import App from './App.vue'
import { firebaseApp } from './firebase'

createApp(App)
  .use(VueFire, { firebaseApp })
  .mount('#app')

Eine Sammlung lesen

useCollection gibt eine reaktive Referenz zurück, die Firestore befüllt und anschließend aktuell hält:

src/components/ListeAvis.vue
<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>

Das ist alles: Die Schleife v-for zeigt die Sammlung wie jedes andere Array an. Öffne die Firebase-Konsole und ändere ein Dokument: Die Liste ändert sich im Browser ohne Neuladen. VueFire schließt das Abonnement beim Unmount der Komponente, was das klassische Leck durch vergessene Listener verhindert.

Für ein einzelnes Dokument folgt useDocument derselben Logik:

javascript
import { doc } from 'firebase/firestore'
import { useDocument } from 'vuefire'

const produit = useDocument(doc(db, 'produits', '2234'))

Filtern und sortieren

Abfragen setzt du aus query, where, orderBy und limit zusammen:

javascript
import { collection, limit, orderBy, query, where } from 'firebase/firestore'

const meilleursAvis = useCollection(
  query(
    collection(db, 'avis'),
    where('note', '>=', 4),
    orderBy('note', 'desc'),
    limit(10)
  )
)

Eine Abfrage, die einen Filter und eine Sortierung auf verschiedenen Feldern kombiniert, braucht einen zusammengesetzten Index. Firestore verweigert die Abfrage und zeigt in der Konsole einen Link an, der den Index mit einem Klick anlegt, das ist die nützlichste Fehlermeldung des Produkts.

Schreiben

Schreibzugriffe laufen über die Funktionen des SDK, nicht über VueFire. Häng sie an ein Formular, um Dokumente aus der Oberfläche heraus anzulegen:

src/components/FormulaireAvis.vue
import {
  addDoc, collection, deleteDoc, doc, serverTimestamp, setDoc, updateDoc
} from 'firebase/firestore'
import { db } from '@/firebase'

// von Firestore erzeugte ID
await addDoc(collection(db, 'avis'), {
  nom: 'Damien',
  note: 5,
  creeLe: serverTimestamp()
})

// selbst gewählte ID (legt an oder ersetzt)
await setDoc(doc(db, 'avis', 'avis-2234'), { nom: 'Damien', note: 5 })

// einzelne Felder ändern
await updateDoc(doc(db, 'avis', 'avis-2234'), { note: 4 })

// löschen
await deleteDoc(doc(db, 'avis', 'avis-2234'))

serverTimestamp() überlässt den Zeitstempel dem Server: Die Uhr auf dem Rechner der Besucherin ist nicht verlässlich.

Gegen den Emulator entwickeln

Direkt auf dem Produktionsprojekt zu arbeiten, verdirbt die Daten und frisst das Kontingent. Die Firebase-Emulator-Suite lässt Firestore lokal laufen.

bash
npm install -D firebase-tools
npx firebase init emulators     # Firestore ankreuzen
npx firebase emulators:start --only firestore --project demo-boutique

Eine Projekt-ID, die mit demo- beginnt, sagt dem Emulator, dass er ohne Konto und ohne Abrechnung arbeiten soll.

Auf Seiten der Anwendung verbindest du das SDK nur in der Entwicklung mit dem Emulator:

src/firebase/index.js
import { connectFirestoreEmulator, getFirestore } from 'firebase/firestore'

export const db = getFirestore(firebaseApp)

if (import.meta.env.DEV) {
  connectFirestoreEmulator(db, '127.0.0.1', 8080)
}
Der Emulator verlangt Java 21

Seit firebase-tools 15 lässt eine ältere JDK-Version den Start mit der Meldung „firebase-tools no longer supports Java version before 21“ scheitern. Prüf das mit java -version.

Die Sicherheitsregeln

Ohne Regeln ist die Datenbank entweder dicht oder für alle offen. Der beim Anlegen vorgeschlagene „Test“-Modus läuft nach dreißig Tagen ab, lass ihn nicht in Produktion stehen.

firestore.rules
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    match /avis/{avisId} {
      // öffentlicher Lesezugriff
      allow read: if true;

      // Schreibzugriff nur für angemeldete Personen, auf ihre eigene Bewertung
      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;
    }
  }
}

Auch die Regeln lassen sich gegen den Emulator schreiben und testen, statt ein Loch erst in Produktion zu entdecken.

Was sich seit SDK 8 geändert hat

Viele Beispiele, die noch online stehen, benutzen die alte Namespace-API. Seit Firebase 9 funktioniert sie so nicht mehr:

javascript
// altes SDK (8 und älter) — funktioniert nicht mehr
import firebase from 'firebase'
const db = firebase.initializeApp(config).database()
db.ref('avis').push({ nom: 'Damien' })

// modulares SDK (9 und neuer)
import { initializeApp } from 'firebase/app'
import { addDoc, collection, getFirestore } from 'firebase/firestore'
const db = getFirestore(initializeApp(config))
await addDoc(collection(db, 'avis'), { nom: 'Damien' })

Die Aufteilung in importierte Funktionen ist keine Kosmetik: Sie erlaubt dem Bundler, nur das zu behalten, was du auch benutzt. Bei einer Anwendung, die Firestore nur liest, ist der Größenunterschied deutlich.

Bei VueFire sind die alte Option firebase: { … } in den Komponenten und das Objekt $firebaseRefs verschwunden: Alles läuft über useCollection und useDocument.

Weiterlesen

Dieser Aufbau setzt Komponenten und Reaktivität in Vue voraus. Wenn dir das fehlt, fang mit dem Vue-3-Tutorial für Einsteiger an. Um Firebase-Daten zwischen weit auseinanderliegenden Komponenten zu teilen, ist ein Pinia-Store, der die Firestore-Aufrufe kapselt, ein gutes Muster.

Häufige Fehler

Einem Tutorial für das SDK 8 folgen firebase.initializeApp(config).database() und das globale Objekt firebase funktionieren seit Version 9 nicht mehr. Alles läuft über importierte Funktionen.
Die alte VueFire-API benutzen Die Option firebase: { … } in den Komponenten und $firebaseRefs sind verschwunden: Nimm useCollection und useDocument.
Den API-Schlüssel für ein Geheimnis halten Er landet im Bundle und autorisiert von sich aus nichts. Die Sicherheit hängt an den Firestore-Regeln.
Die Regeln im Testmodus lassen Sie laufen nach dreißig Tagen ab und lassen die Datenbank bis dahin für Schreibzugriffe offen.
Emulator und Java-Version Seit firebase-tools 15 lässt ein JDK vor Version 21 den Start scheitern.

FirebaseJavaScriptVue.js

Damien Flandrin Webentwickler seit 2010, Gründer von Gekkode und Email Impact. Jeder Artikel wird vor der Veröffentlichung an einem echten Projekt getestet. Kontakt
Newsletter

Neue Tests, Tutorials und Projekte, per E-Mail.

Reproduzierbare Tests, versionierter Code, datierte Ergebnisse. Niemals Spam.