Sie entwickeln eine App. Benutzer müssen sich anmelden. Daten müssen in Echtzeit synchronisiert werden. Dateien benötigen Speicherplatz. Sie könnten wochenlang Server einrichten, Datenbanken konfigurieren und die Infrastruktur verwalten. Oder Sie nutzen Firebase.
Firebase betreibt über 1,5 Millionen Apps, darunter The New York Times, Duolingo und Alibaba. Entwickler wählen es, weil es die Komplexität des Backends reduziert. Sie konzentrieren sich auf Funktionen, nicht auf die Serverwartung. Doch die Firebase API hat ihre Eigenheiten. Authentifizierungsabläufe verwirren Anfänger. Datenbankregeln stellen erfahrene Entwickler vor Herausforderungen. Cloud Functions wirken magisch, bis man die Auslöser versteht.
Ich habe Firebase in Produktions-Apps integriert, die Millionen von Nutzern bedienen. Ich habe jeden möglichen Fehler gemacht: Dienstkontoschlüssel offengelegt, ineffiziente Abfragen geschrieben, fehlerhafte Funktionen bereitgestellt. Dieser Leitfaden destilliert diese Lehren.
Sie lernen Authentifizierung, Datenbankoperationen, Cloud Functions und Speicherverwaltung. Sie werden funktionierenden Code sehen, nicht nur Theorie. Sie werden die Fallstricke vermeiden, die in der Produktion zu Problemen führen.
Was ist die Firebase API und warum ist sie wichtig?
Firebase ist keine einzelne API. Es ist eine Suite von Backend-Diensten, auf die über vereinheitlichte SDKs und REST-Endpunkte zugegriffen wird.
Wichtige Firebase-Dienste
| Dienst | Zweck | API-Typ |
|---|---|---|
| Authentifizierung | Benutzeranmeldung und Identität | SDK + REST |
| Firestore-Datenbank | NoSQL-Dokumentdatenbank | SDK + REST |
| Echtzeit-Datenbank | JSON-Echtzeit-Synchronisation | SDK + REST |
| Cloud-Speicher | Dateispeicherung und CDN | SDK + REST |
| Cloud Functions | Serverloses Computing | Bereitstellungs-CLI |
| Hosting | Statisches Webhosting | Bereitstellungs-CLI |
| Cloud Messaging | Push-Benachrichtigungen | HTTP v1 API |
Wann Firebase sinnvoll ist
Firebase löst bestimmte Probleme gut:
Nutzen Sie Firebase, wenn:
- Sie Echtzeit-Synchronisation benötigen (Chat, Zusammenarbeit, Live-Updates)
- Sie eine serverlose Architektur wünschen (keine Infrastrukturverwaltung)
- Sie mobile oder Web-Apps entwickeln (SDKs handhaben Plattformunterschiede)
- Sie Offline-Unterstützung benötigen (SDKs cachen Daten automatisch)
- Sie eine integrierte Authentifizierung wünschen (Google, Apple, E-Mail, Telefonanmeldung)
Verzichten Sie auf Firebase, wenn:
- Sie komplexe relationale Abfragen benötigen (verwenden Sie stattdessen PostgreSQL)
- Sie strenge Anforderungen an die Datenresidenz haben (Firebase-Regionen sind begrenzt)
- Sie vollständige SQL-Funktionen benötigen (Firestore-Abfragebeschränkungen existieren)
- Kosten bei Skalierung wichtiger sind als Entwicklungsgeschwindigkeit (Self-Hosting ist günstiger)
Die Firebase API-Architektur
Firebase verwendet einen hybriden Ansatz:
┌─────────────────────────────────────────────────────────┐
│ Ihre Anwendung │
├─────────────────────────────────────────────────────────┤
│ Firebase SDK (Client) │
│ - Handhabt Auth-Tokens automatisch │
│ - Verwaltet Offline-Cache │
│ - Echtzeit-Listener │
└─────────────────────────────────────────────────────────┘
│
│ HTTPS + WebSocket
▼
┌─────────────────────────────────────────────────────────┐
│ Firebase Backend │
├──────────────┬──────────────┬──────────────┬────────────┤
│ Auth │ Firestore │ Speicher │ Funktionen │
│ Dienst │ Datenbank │ Dienst │ Laufzeit │
└──────────────┴──────────────┴──────────────┴────────────┘
Client-SDKs abstrahieren die HTTP-Schicht. Im Hintergrund wird jede Operation in REST API-Aufrufe mit JWT-Authentifizierung übersetzt.
Firebase Authentifizierung: Vollständige Einrichtung
Die Authentifizierung ist Ihre erste Firebase-Integration. Wenn Sie dies falsch machen, schlägt alles andere fehl.
Schritt 1: Firebase-Projekt erstellen
- Gehen Sie zur Firebase Console

Klicken Sie auf „Projekt hinzufügen“ und geben Sie den Projektnamen ein (keine Leerzeichen).

Google Analytics aktivieren (optional, aber empfohlen)

Klicken Sie auf „Projekt erstellen“

Warten Sie 30 Sekunden auf die Bereitstellung. Sie sehen dann das Projekt-Dashboard.
Schritt 2: Ihre App registrieren
Für Web-Apps:
// In Firebase Console > Projekteinstellungen > Allgemein
// Klicken Sie auf "App hinzufügen" > Web-Symbol
// Web-App registrieren
const firebaseConfig = {
apiKey: "AIzaSyDxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
authDomain: "your-app.firebaseapp.com",
projectId: "your-app",
storageBucket: "your-app.appspot.com",
messagingSenderId: "123456789012",
appId: "1:123456789012:web:abc123def456"
};
// Firebase initialisieren
import { initializeApp } from 'firebase/app';
const app = initializeApp(firebaseConfig);
Für iOS-Apps:
Laden Sie GoogleService-Info.plist herunter und fügen Sie es dem Xcode-Projekt hinzu. Stellen Sie sicher, dass „Target Membership“ Ihre App einschließt.
Für Android-Apps:
Laden Sie google-services.json herunter und legen Sie es im Verzeichnis app/ ab. Fügen Sie es zu build.gradle hinzu:
// build.gradle auf Projektebene
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.4.0'
}
}
// build.gradle auf App-Ebene
plugins {
id 'com.google.gms.google-services'
}
Schritt 3: Authentifizierungsmethoden aktivieren
In der Firebase Console > Authentifizierung > Anmeldemethode:
- E-Mail/Passwort: Für die traditionelle Registrierung aktivieren
- Google: Fügen Sie den SHA-1-Zertifikatsfingerabdruck (Android) oder die Bundle ID (iOS) hinzu
- Apple: Für iOS-Apps erforderlich, wenn Sie eine soziale Anmeldung aktivieren
- Telefon: Für SMS-Authentifizierung aktivieren (erfordert Abrechnung)
Schritt 4: Authentifizierungsablauf implementieren
E-Mail/Passwort-Registrierung:
import {
createUserWithEmailAndPassword,
getAuth,
updateProfile
} from 'firebase/auth';
const auth = getAuth(app);
async function signUp(email, password, displayName) {
try {
const userCredential = await createUserWithEmailAndPassword(
auth,
email,
password
);
// Anzeigenamen festlegen
await updateProfile(userCredential.user, {
displayName: displayName
});
console.log('User created:', userCredential.user.uid);
return userCredential.user;
} catch (error) {
// Spezifische Fehlercodes behandeln
switch (error.code) {
case 'auth/email-already-in-use':
throw new Error('Diese E-Mail ist bereits registriert');
case 'auth/weak-password':
throw new Error('Passwort muss mindestens 6 Zeichen lang sein');
case 'auth/invalid-email':
throw new Error('Ungültige E-Mail-Adresse');
default:
throw new Error('Registrierung fehlgeschlagen: ' + error.message);
}
}
}
E-Mail/Passwort-Anmeldung:
import {
signInWithEmailAndPassword,
signOut
} from 'firebase/auth';
async function signIn(email, password) {
try {
const userCredential = await signInWithEmailAndPassword(
auth,
email,
password
);
const user = userCredential.user;
// ID-Token für API-Aufrufe abrufen
const idToken = await user.getIdToken();
console.log('Auth token:', idToken);
return user;
} catch (error) {
switch (error.code) {
case 'auth/user-not-found':
throw new Error('Kein Konto mit dieser E-Mail');
case 'auth/wrong-password':
throw new Error('Falsches Passwort');
case 'auth/too-many-requests':
throw new Error('Zu viele Versuche. Versuchen Sie es später erneut');
default:
throw new Error('Anmeldung fehlgeschlagen');
}
}
}
async function logOut() {
await signOut(auth);
console.log('Benutzer abgemeldet');
}
Google-Anmeldung (Web):
import {
GoogleAuthProvider,
signInWithPopup
} from 'firebase/auth';
async function signInWithGoogle() {
const provider = new GoogleAuthProvider();
// Zusätzliche Scopes anfordern
provider.addScope('email');
provider.addScope('profile');
try {
const result = await signInWithPopup(auth, provider);
const user = result.user;
// Google OAuth-Token abrufen
const credential = GoogleAuthProvider.credentialFromResult(result);
const googleAccessToken = credential.accessToken;
return user;
} catch (error) {
if (error.code === 'auth/popup-closed-by-user') {
throw new Error('Anmeldung abgebrochen');
}
throw new Error('Google-Anmeldung fehlgeschlagen');
}
}
Schritt 5: Routen mit Authentifizierungsstatus schützen
import { onAuthStateChanged } from 'firebase/auth';
// Authentifizierungsstatusänderungen abonnieren
onAuthStateChanged(auth, (user) => {
if (user) {
// Benutzer ist angemeldet
console.log('User:', user.email);
// Weiterleitung zum Dashboard
window.location.href = '/dashboard';
} else {
// Benutzer ist abgemeldet
console.log('No user');
// Weiterleitung zur Anmeldung
window.location.href = '/login';
}
});
Häufige Authentifizierungsfehler
Fehler 1: Token-Aktualisierung wird nicht behandelt
Das Firebase SDK aktualisiert Token automatisch. Wenn Sie Token jedoch serverseitig cachen, laufen sie nach 1 Stunde ab. Überprüfen Sie Token immer bei jeder Anfrage oder implementieren Sie eine Aktualisierungslogik.
Fehler 2: Admin-Anmeldedaten im Client-Code offenlegen
Verwenden Sie niemals Dienstkontoschlüssel in Client-Apps. Dienstkonten umgehen Sicherheitsregeln. Verwenden Sie sie nur in vertrauenswürdigen Serverumgebungen.
Fehler 3: E-Mail-Verifizierung überspringen
import { sendEmailVerification } from 'firebase/auth';
async function sendVerificationEmail(user) {
await sendEmailVerification(user);
console.log('Verifizierungs-E-Mail gesendet');
}
// Verifizierungsstatus prüfen
if (!auth.currentUser.emailVerified) {
console.log('E-Mail nicht verifiziert');
// Zugriff einschränken
}
Firestore-Datenbank: Operationen und Abfragen
Firestore ist die NoSQL-Datenbank von Firebase. Dokumente werden in Sammlungen organisiert. Abfragen skalieren automatisch.
Datenstruktur
Ihr-Projekt (Stamm)
└── Benutzer (Sammlung)
├── Benutzer-ID123 (Dokument)
│ ├── name: "John"
│ ├── email: "john@example.com"
│ └── Beiträge (Unterkollektion)
│ ├── Beitrags-ID1 (Dokument)
│ └── Beitrags-ID2 (Dokument)
└── Benutzer-ID456 (Dokument)
Firestore initialisieren
import { getFirestore } from 'firebase/firestore';
const db = getFirestore(app);
Dokumente erstellen
import {
collection,
addDoc,
setDoc,
doc
} from 'firebase/firestore';
// Option 1: Automatisch generierte ID
async function createUser(userData) {
const docRef = await addDoc(collection(db, 'users'), userData);
console.log('Dokument geschrieben mit ID:', docRef.id);
return docRef.id;
}
// Option 2: Benutzerdefinierte ID
async function createUserWithId(userId, userData) {
await setDoc(doc(db, 'users', userId), userData);
console.log('Dokument geschrieben mit benutzerdefinierter ID:', userId);
}
// Verwendung
const userId = await createUser({
name: 'Alice',
email: 'alice@example.com',
createdAt: new Date(),
role: 'user'
});
Dokumente lesen
import {
getDoc,
getDocs,
query,
where,
orderBy,
limit
} from 'firebase/firestore';
// Einzelnes Dokument abrufen
async function getUser(userId) {
const docRef = doc(db, 'users', userId);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
return docSnap.data();
} else {
throw new Error('Benutzer nicht gefunden');
}
}
// Abfrage mit Filtern
async function getUsersByRole(role) {
const q = query(
collection(db, 'users'),
where('role', '==', role),
orderBy('createdAt', 'desc'),
limit(10)
);
const querySnapshot = await getDocs(q);
const users = [];
querySnapshot.forEach((doc) => {
users.push({ id: doc.id, ...doc.data() });
});
return users;
}
// Verwendung
const adminUsers = await getUsersByRole('admin');
console.log('Admin-Benutzer:', adminUsers);
Dokumente aktualisieren
import {
updateDoc,
increment,
arrayUnion,
arrayRemove
} from 'firebase/firestore';
async function updateUser(userId, updates) {
const userRef = doc(db, 'users', userId);
await updateDoc(userRef, updates);
}
// Atomare Operationen
await updateUser('userId123', {
loginCount: increment(1),
tags: arrayUnion('premium', 'beta-tester'),
lastLogin: new Date()
});
// Aus Array entfernen
await updateUser('userId123', {
tags: arrayRemove('beta-tester')
});
Dokumente löschen
import { deleteDoc } from 'firebase/firestore';
async function deleteUser(userId) {
await deleteDoc(doc(db, 'users', userId));
console.log('Benutzer gelöscht');
}
Echtzeit-Listener
import { onSnapshot } from 'firebase/firestore';
// Einzelnes Dokument überwachen
const unsubscribe = onSnapshot(
doc(db, 'users', userId),
(doc) => {
console.log('Benutzer aktualisiert:', doc.data());
},
(error) => {
console.error('Listen-Fehler:', error);
}
);
// Abfrageergebnisse überwachen
const q = query(collection(db, 'posts'), where('published', '==', true));
const unsubscribeQuery = onSnapshot(q, (snapshot) => {
const posts = snapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
}));
console.log('Veröffentlichte Beiträge:', posts);
});
// Überwachung beenden
unsubscribe();
unsubscribeQuery();
Firestore-Sicherheitsregeln
Ohne ordnungsgemäße Regeln kann jeder Ihre Daten lesen. Legen Sie Regeln in der Firebase Console > Firestore > Regeln fest:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Hilfsfunktion
function isAuthenticated() {
return request.auth != null;
}
function isOwner(userId) {
return request.auth.uid == userId;
}
// Benutzersammlung
match /users/{userId} {
allow read: if isAuthenticated();
allow create: if isAuthenticated() && isOwner(userId);
allow update, delete: if isOwner(userId);
}
// Beitragssammlung
match /posts/{postId} {
allow read: if true; // Öffentlicher Lesezugriff
allow create: if isAuthenticated();
allow update, delete: if resource.data.authorId == request.auth.uid;
}
// Private Unterkollektion
match /users/{userId}/private/{document} {
allow read, write: if isOwner(userId);
}
}
}
Abfragebeschränkungen
Firestore hat Einschränkungen:
- Keine OR-Abfragen (verwenden Sie
inmit einem Array oder mehreren Abfragen) - Keine Wildcard-Suchen (verwenden Sie Algolia oder Meilisearch für Volltextsuche)
- Zusammengesetzte Abfragen benötigen Indizes (Firestore erstellt Einzelfeldindizes automatisch)
- Begrenzung auf 30 Disjunktionen in
in-Abfragen
Workaround für OR-Abfragen:
// Statt: where('status', '==', 'active') ODER where('status', '==', 'pending')
const activeQuery = query(
collection(db, 'tasks'),
where('status', '==', 'active')
);
const pendingQuery = query(
collection(db, 'tasks'),
where('status', '==', 'pending')
);
const [activeSnap, pendingSnap] = await Promise.all([
getDocs(activeQuery),
getDocs(pendingQuery)
]);
// Ergebnisse im Client zusammenführen
Cloud Functions: Serverlose Backend-Logik
Cloud Functions führen Backend-Code aus, ohne Server verwalten zu müssen. Sie werden durch Datenbankänderungen, HTTP-Anfragen oder geplante Ereignisse ausgelöst.
Einrichtung
# Firebase CLI installieren
npm install -g firebase-tools
# Anmelden
firebase login
# Funktionen in Ihrem Projekt initialisieren
firebase init functions
# Auswählen: JavaScript, ESLint ja, Express.js nein
HTTP-Funktionen (API-Endpunkte)
// functions/index.js
const { onRequest } = require('firebase-functions/v2/https');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
// Öffentlicher Endpunkt
exports.getPublicData = onRequest(async (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
try {
const snapshot = await db.collection('public').get();
const data = snapshot.docs.map(doc => doc.data());
res.json({ success: true, data });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Geschützter Endpunkt (Auth-Token überprüfen)
exports.getUserProfile = onRequest(async (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
// Token aus dem Authorization-Header abrufen
const authHeader = req.headers.authorization || '';
const token = authHeader.split('Bearer ')[1];
if (!token) {
return res.status(401).json({ error: 'Nicht autorisiert' });
}
try {
// Token überprüfen
const decodedToken = await admin.auth().verifyIdToken(token);
const userId = decodedToken.uid;
// Benutzerdaten abrufen
const userDoc = await db.collection('users').doc(userId).get();
if (!userDoc.exists) {
return res.status(404).json({ error: 'Benutzer nicht gefunden' });
}
res.json({
success: true,
data: { id: userId, ...userDoc.data() }
});
} catch (error) {
res.status(401).json({ error: 'Ungültiges Token' });
}
});
Bereitstellen:
firebase deploy --only functions:getUserProfile
Aufruf vom Client:
async function getUserProfile(token) {
const response = await fetch(
'https://us-central1-your-app.cloudfunctions.net/getUserProfile',
{
headers: {
'Authorization': `Bearer ${token}`
}
}
);
const data = await response.json();
return data;
}
Datenbank-Trigger
const { onDocumentWritten } = require('firebase-functions/v2/firestore');
// Trigger, wenn sich ein Benutzerdokument ändert
exports.onUserUpdate = onDocumentWritten(
'users/{userId}',
async (event) => {
const userId = event.params.userId;
const before = event.data?.before?.data();
const after = event.data?.after?.data();
// Prüfen, ob sich die E-Mail geändert hat
if (before?.email !== after?.email) {
console.log(`User ${userId} email changed: ${before?.email} → ${after?.email}`);
// Benachrichtigungs-E-Mail senden
await admin.auth().getUser(userId);
// Fügen Sie hier Ihre E-Mail-Logik ein
}
}
);
// Trigger bei Erstellung eines neuen Beitrags
exports.onNewPost = onDocumentWritten(
'posts/{postId}',
async (event) => {
const post = event.data?.after?.data();
if (!post) return; // Dokument gelöscht
// Prüfen, ob dies ein neues Dokument ist
if (!event.data?.before?.exists) {
console.log('New post created:', post.title);
// Follower benachrichtigen
const followersSnap = await admin.firestore()
.collection('users')
.where('following', 'array-contains', post.authorId)
.get();
const notifications = followersSnap.docs.map(doc => ({
userId: doc.id,
postId: event.params.postId,
type: 'new_post',
createdAt: admin.firestore.FieldValue.serverTimestamp()
}));
const batch = admin.firestore().batch();
notifications.forEach(notif => {
const ref = admin.firestore().collection('notifications').doc();
batch.set(ref, notif);
});
await batch.commit();
}
}
);
Geplante Funktionen (Cron-Jobs)
const { onSchedule } = require('firebase-functions/v2/scheduler');
// Jeden Tag um Mitternacht UTC ausführen
exports.dailyCleanup = onSchedule('every 24 hours', async (event) => {
console.log('Tägliche Bereinigung läuft');
// Alte Benachrichtigungen löschen (30+ Tage)
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
const oldNotifs = await admin.firestore()
.collection('notifications')
.where('createdAt', '<', thirtyDaysAgo)
.get();
const batch = admin.firestore().batch();
oldNotifs.forEach(doc => batch.delete(doc.ref));
await batch.commit();
console.log(`Gelöscht ${oldNotifs.size} alte Benachrichtigungen`);
});
Umgebungskonfiguration
# Umgebungsvariablen setzen
firebase functions:config:set \
stripe.secret="sk_test_xxx" \
email.api_key="key_xxx"
# Zugriff in Funktionen
const config = require('firebase-functions/config');
const stripe = require('stripe')(config.stripe.secret);
Cloud Storage: Datei-Upload und -Verwaltung
Speichern Sie Benutzer-Uploads, Bilder und Dateien mit automatischer CDN-Verteilung.
Speicherregeln einrichten
// Firebase Console > Storage > Regeln
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
// Ordner für Benutzer-Uploads
match /users/{userId}/{allPaths=**} {
allow read: if true; // Öffentlicher Lesezugriff
allow write: if request.auth.uid == userId;
allow delete: if request.auth.uid == userId;
}
// Öffentliche Assets
match /public/{allPaths=**} {
allow read: if true;
allow write: if false; // Nur Admin über Firebase Console
}
}
}
Dateien hochladen (Client)
import {
getStorage,
ref,
uploadBytesResumable,
getDownloadURL
} from 'firebase/storage';
const storage = getStorage(app);
async function uploadProfileImage(userId, file) {
// Speicherreferenz erstellen
const storageRef = ref(storage, `users/${userId}/profile/${file.name}`);
// Datei hochladen
const uploadTask = uploadBytesResumable(storageRef, file);
return new Promise((resolve, reject) => {
uploadTask.on(
'state_changed',
(snapshot) => {
// Fortschritt verfolgen
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log(`Upload: ${progress.toFixed(0)}%`);
},
(error) => {
// Fehler behandeln
switch (error.code) {
case 'storage/unauthorized':
reject(new Error('Sie haben keine Berechtigung'));
break;
case 'storage/canceled':
reject(new Error('Upload abgebrochen'));
break;
default:
reject(new Error('Upload fehlgeschlagen'));
}
},
async () => {
// Upload abgeschlossen
const downloadURL = await getDownloadURL(uploadTask.snapshot.ref);
console.log('Datei verfügbar unter:', downloadURL);
resolve(downloadURL);
}
);
});
}
// Verwendung
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
if (file) {
const imageUrl = await uploadProfileImage(auth.currentUser.uid, file);
// URL in Firestore speichern
await updateDoc(doc(db, 'users', auth.currentUser.uid), {
profileImage: imageUrl
});
}
Dateien herunterladen
import { getDownloadURL } from 'firebase/storage';
async function getProfileImage(userId) {
const imageRef = ref(storage, `users/${userId}/profile/avatar.png`);
try {
const url = await getDownloadURL(imageRef);
return url;
} catch (error) {
if (error.code === 'storage/object-not-found') {
return null; // Kein Profilbild
}
throw error;
}
}
Dateien löschen
import { deleteObject } from 'firebase/storage';
async function deleteProfileImage(userId) {
const imageRef = ref(storage, `users/${userId}/profile/avatar.png`);
await deleteObject(imageRef);
console.log('Profilbild gelöscht');
}
Firebase APIs mit Apidog testen
Firebase bietet REST APIs für alle Dienste. Direktes Testen hilft, Probleme zu debuggen und die zugrunde liegenden Anfragen zu verstehen.
Firebase REST API importieren
- Apidog öffnen
- Neues Projekt erstellen: „Firebase API“
- OpenAPI-Spezifikation aus der Firebase-Dokumentation importieren
- Oder Endpunkte manuell hinzufügen:
Firestore REST-Endpunkt:
POST https://firestore.googleapis.com/v1/projects/{projectId}/databases/(default)/documents
Authorization: Bearer {oauth2_token}
Content-Type: application/json
{
"fields": {
"name": { "stringValue": "John" },
"email": { "stringValue": "john@example.com" },
"age": { "integerValue": 30 }
}
}
Authentifizierungs-Endpunkt:
POST https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key={api_key}
Content-Type: application/json
{
"email": "user@example.com",
"password": "secret123",
"returnSecureToken": true
}
Authentifizierungsablauf testen
- Anfrage erstellen: „Anmelden“
- Methode festlegen: POST
- E-Mail/Passwort im Body hinzufügen
- Antwort-Token als Umgebungsvariable speichern
{{token}}in nachfolgenden Anfragen verwenden
Sicherheitsregeln debuggen
Verwenden Sie die Firebase Emulator Suite für lokale Tests:
# Emulator starten
firebase emulators:start
# Gegen lokales Firestore testen
# http://localhost:8080
Best Practices für die Produktion
1. Richtige Fehlerbehandlung implementieren
// Wiederholungslogik für vorübergehende Fehler
async function firestoreWithRetry(operation, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await operation();
} catch (error) {
if (
error.code === 'unavailable' ||
error.code === 'deadline-exceeded'
) {
const delay = Math.pow(2, i) * 1000; // Exponentielles Backoff
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}
2. Abfrageleistung optimieren
Fügen Sie zusammengesetzte Indizes für Abfragen mit mehreren Feldern hinzu:
// Diese Abfrage benötigt einen zusammengesetzten Index
const q = query(
collection(db, 'posts'),
where('category', '==', 'tech'),
where('views', '>', 1000),
orderBy('views', 'desc')
);
Firestore fordert Sie beim Ausführen dieser Abfrage mit einem direkten Link auf, den Index zu erstellen.
3. Batch-Operationen
import { writeBatch } from 'firebase/firestore';
async function bulkUpdate(userIds, updates) {
const batch = writeBatch(db);
userIds.forEach(id => {
const ref = doc(db, 'users', id);
batch.update(ref, updates);
});
await batch.commit();
console.log(`Aktualisiert ${userIds.length} Benutzer`);
}
// Max. 500 Operationen pro Batch
4. Kosten überwachen
Firebase-Preise:
| Dienst | Kostenlose Stufe | Kostenpflichtig |
|---|---|---|
| Firestore | 50K Lesevorgänge/Tag | $0,036/100K Lesevorgänge |
| Speicher | 5 GB | $0,023/GB |
| Funktionen | 2 Mio. Aufrufe | $0,40/1 Mio. |
| Auth | 10K/Monat | $0,0055/100K |
Legen Sie Budgetwarnungen in der Google Cloud Console fest.
5. Dienstkonten sichern
// FALSCH: Niemals im Client-Code tun
admin.initializeApp({
credential: admin.credential.cert(require('./serviceAccountKey.json'))
});
// KORREKT: Nur in Serverumgebung verwenden
const serviceAccount = JSON.parse(process.env.FIREBASE_SERVICE_ACCOUNT);
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
6. Offline-Szenarien behandeln
// Offline-Persistenz aktivieren (Web)
import { enableMultiTabIndexedDbPersistence } from 'firebase/firestore';
enableMultiTabIndexedDbPersistence(db)
.catch((err) => {
if (err.code === 'failed-precondition') {
// Mehrere Tabs geöffnet
} else if (err.code === 'unimplemented') {
// Browser unterstützt nicht
}
});
// Konnektivität überwachen
import { onSnapshot } from 'firebase/firestore';
onSnapshot(doc(db, 'status', 'online'), (doc) => {
if (!doc.exists()) {
console.log('Sie sind offline');
// Offline-Benutzeroberfläche anzeigen
}
});
Häufige Firebase API-Probleme und Lösungen
Problem 1: Berechtigungsverweigerungsfehler
Symptom: Fehler: 7 PERMISSION_DENIED
Ursache: Sicherheitsregeln blockieren die Operation
Lösung:
- Regeln in der Firebase Console prüfen
- Überprüfen Sie, ob
request.auth.uiddem erwarteten Benutzer entspricht - Regeln mit dem Rules Playground testen
Problem 2: Token-Ablauf
Symptom: Fehler: ID-Token abgelaufen
Lösung:
// Token-Aktualisierung erzwingen
const user = auth.currentUser;
if (user) {
await user.getIdToken(true); // Aktualisierung erzwingen
}
Problem 3: Kaltstartlatenz
Symptom: Cloud Functions benötigen beim ersten Aufruf 2-5 Sekunden
Lösung:
// Funktionen mit geplanten Pings warmhalten
exports.keepWarm = onSchedule('every 60 seconds', async () => {
await fetch('https://your-function.cloudfunctions.net/health');
});
Problem 4: Abfrage liefert leere Ergebnisse
Symptom: Abfrage sollte Daten zurückgeben, liefert aber ein leeres Array
Ursache: Fehlender Index oder falsche Feldreihenfolge
Lösung: Überprüfen Sie in der Firestore Console > Indizes auf erforderliche zusammengesetzte Indizes.
Anwendungsfälle aus der Praxis
Fintech-App: Echtzeit-Transaktions-Updates
Ein Zahlungs-Startup nutzte Firebase Firestore, um Echtzeit-Transaktionsbenachrichtigungen zu erstellen. Wenn eine Zahlung verarbeitet wird, lösen Cloud Functions innerhalb von 200 ms Updates für alle verbundenen Admin-Dashboards aus. Ergebnis: Eine Reduzierung der Support-Tickets zu „ausstehenden“ Transaktionen um 40 %.
E-Commerce: Bestandsynchronisation
Ein Online-Händler synchronisiert seinen Bestand über Web, iOS und Android mithilfe von Firestore-Listeners. Wenn sich der Lagerbestand ändert, aktualisieren sich alle Clients automatisch. Die Offline-Persistenz stellt sicher, dass Lagerarbeiter Artikel ohne Konnektivität scannen können, mit automatischer Synchronisation bei erneuter Verbindung.
SaaS: Multi-Tenant-Authentifizierung
Eine B2B-Plattform verwendet Firebase Auth mit benutzerdefinierten Ansprüchen für rollenbasierten Zugriff. Admin-Benutzer erhalten erweiterte Berechtigungen über Cloud Functions, die gegen Firestore-Tenant-Konfigurationen validieren. Eine einzige Codebasis bedient über 500 Organisationen mit isolierten Daten.
Fazit
Die Firebase API-Integration umfasst vier Kerndienste:
- Authentifizierung: E-Mail-, Google-, Apple-Anmeldung mit JWT-Tokens
- Firestore: NoSQL-Datenbank mit Echtzeit-Listenern und Sicherheitsregeln
- Cloud Functions: Serverloses Backend, ausgelöst durch Ereignisse oder HTTP
- Speicher: Datei-Uploads mit CDN-Verteilung
Sie haben Authentifizierungsabläufe, Datenbankoperationen, Funktionsbereitstellung und Dateiverwaltung gelernt. Sie haben Produktionsmuster kennengelernt: Fehlerbehandlung, Batching, Offline-Unterstützung und Sicherheit.
FAQ
Ist Firebase kostenlos nutzbar?
Ja, Firebase bietet einen großzügigen kostenlosen Tarif (Spark Plan) mit 5 GB Speicherplatz, 50.000 Firestore-Lesevorgängen/Tag, 2 Millionen Cloud Function-Aufrufen und 10.000 Auth-Benutzern/Monat. Kostenpflichtige Tarife (Blaze) basieren auf Pay-as-you-go-Preisen.
Kann ich Firebase mit bestehenden Datenbanken verwenden?
Ja. Verwenden Sie Firebase Extensions, um mit PostgreSQL, MySQL oder MongoDB zu synchronisieren. Oder rufen Sie externe APIs von Cloud Functions auf, um sie in bestehende Systeme zu integrieren.
Wie migriere ich von Firebase zu einer anderen Plattform?
Exportieren Sie Daten mit Firestore-Exportfunktionen oder der Firebase CLI. Für große Datensätze verwenden Sie die Dataflow-Export-Pipeline. Die Komplexität der Migration hängt von Ihrer Datenstruktur ab.
Unterstützt Firebase GraphQL?
Nicht nativ. Verwenden Sie Drittanbieterlösungen wie firestore-graphql oder erstellen Sie eine GraphQL-Schicht mit Cloud Functions und Apollo Server.
Kann ich Firebase On-Premise verwenden?
Nein. Firebase ist nur in der Google Cloud verfügbar. Für selbst gehostete Alternativen ziehen Sie Appwrite, Supabase oder Nhost in Betracht.
Wie handhabe ich Datei-Uploads, die größer als 100 MB sind?
Verwenden Sie fortsetzbare Uploads mit Chunking. Das Firebase SDK handhabt dies automatisch. Für sehr große Dateien verwenden Sie Google Cloud Storage direkt mit signierten URLs.
Was passiert, wenn ich die Firestore-Abfragelimits überschreite?
Abfragen schlagen mit dem Fehler FAILED_PRECONDITION fehl. Fügen Sie die erforderlichen Indizes hinzu oder strukturieren Sie Abfragen neu. Firestore bietet direkte Links zum Erstellen fehlender Indizes in der Fehlermeldung.
Ist Firebase DSGVO-konform?
Ja, Firebase bietet eine DSGVO-konforme Datenverarbeitung. Aktivieren Sie die Datenresidenz in bestimmten Regionen, implementieren Sie den Export/die Löschung von Benutzerdaten und unterzeichnen Sie Googles Datenverarbeitungsnachtrag.
