Firebase Realtime Database ist eine Cloud-JSON-Echtzeit-Datenbank, die Google 2012 für mobile und Webanwendungen veröffentlicht hat. Alle Daten werden in einem großen JSON-Baum gespeichert und über eine WebSocket-Verbindung in Echtzeit zwischen verbundenen Clients synchronisiert. Laut offizieller Dokumentation Firebase, 2025 kann Realtime Database bis zu 200.000 gleichzeitige Verbindungen bedienen und unterstützt bis zu 1.000 gleichzeitige Schreibvorgänge pro Sekunde. Die Datenbank benötigt keine Serverinfrastruktur und stellt SDKs für iOS, Android, Web und Serverplattformen bereit.
Wichtige Punkte
Firebase Realtime Database ist eine Cloud-NoSQL-Datenbank, die Daten in Echtzeit zwischen allen verbundenen Clients speichert und synchronisiert. 2012 als Firebase gestartet (vor der Übernahme durch Google), wurde sie zur ersten Cloud-Echtzeit-Datenbank für mobile Entwickler. Daten werden im JSON-Format dargestellt und in einem hierarchischen Baum organisiert, wobei jeder Knoten einen eindeutigen Pfad hat.
Der Kernwert von Realtime Database ist die integrierte Synchronisation. Wenn eine App Daten auf einem Gerät ändert, erhalten alle anderen verbundenen Clients die Aktualisierung sofort über eine permanente Verbindung. Dies erspart dem Entwickler die Implementierung eines eigenen Synchronisationsmechanismus, WebSocket-Servers oder REST-API für die Datenübertragung zwischen Clients.
Die Datenbank bietet SDKs für alle wichtigen Plattformen: Android (Java, Kotlin), iOS (Swift, Objective-C), Web (JavaScript) und Serverumgebungen über Admin SDK. Laut Google wird Realtime Database in über 1,5 Millionen aktiven Firebase-Projekten weltweit eingesetzt. Trotz des Aufkommens des moderneren Firestore bleibt Realtime Database eine beliebte Wahl für Projekte mit einfachen Datenstrukturen.
Im Gegensatz zu relationalen Datenbanken verwendet Realtime Database keine Tabellen und Zeilen. Alle Daten sind ein einziger JSON-Baum, der verschachtelten JavaScript-Objekten ähnelt. Zum Speichern von Benutzern und ihren Nachrichten wird eine Hierarchie erstellt: users/userId/name und messages/messageId/text. Jeder Pfad im Baum ist ein String, und auf die Daten kann direkt über diesen Pfad zugegriffen werden.
{
"users": {
"user1": {
"name": "Ivan Petrov",
"email": "ivan@example.com"
},
"user2": {
"name": "Maria Sokolova",
"email": "maria@example.com"
}
},
"messages": {
"-Nabc123": {
"text": "Hallo!",
"userId": "user1"
}
}
}
Eine wichtige Eigenschaft ist, dass tiefe Verschachtelung die Leistung beeinträchtigt. Wenn eine App Daten an einem bestimmten Pfad liest, werden alle untergeordneten Knoten dieses Pfads geladen. Daher wird empfohlen, die Datenstruktur so flach wie möglich zu gestalten und Verschachtelungen tiefer als 3-4 Ebenen zu vermeiden. Zur Umgehung dieses Problems wird Denormalisierung verwendet — das Duplizieren von Informationen in verschiedenen Baumknoten.
Realtime Database und Firestore werden oft als zwei Cloud-Echtzeit-Datenbanken von Google verglichen. Die Wahl zwischen ihnen hängt von den spezifischen Projektanforderungen ab: Abfragekomplexität, benötigte Konsistenz und erwartete Last. Das Verständnis der Stärken jeder Datenbank hilft bei der richtigen Architekturentscheidung.
Der Hauptvorteil von Realtime Database ist die niedrige Synchronisationslatenz. Da alle Daten ohne zusätzliche Abstraktionsebenen in einem einzigen JSON-Baum gespeichert sind, erfolgt die Synchronisation schneller als in Firestore. Für Anwendungen, bei denen die Geschwindigkeit der Aktualisierungsübermittlung entscheidend ist (Chats, Online-Spiele, kollaborative Bearbeitungssysteme), ist Realtime Database möglicherweise die geeignetere Wahl.
Realtime Database eignet sich besser für Szenarien mit einfacher Datenstruktur und hoher Aktualisierungshäufigkeit. Typische Beispiele: Chats, Echtzeit-Likes, Tipp-Indikatoren, Benutzerpräsenz-Status. Es ist auch eine gute Wahl für Prototypen und Projekte mit begrenztem Budget, da die Preisgestaltung auf dem Datenvolumen basiert, nicht auf der Anzahl der Operationen.
Andererseits bietet Firestore für Anwendungen mit komplexen Abfragen (Filtern nach mehreren Feldern, Sortieren, Aggregieren) weitaus leistungsfähigere Möglichkeiten. Realtime Database unterstützt nur das Filtern nach einem Parameter und kann Ergebnisse nicht gleichzeitig nach mehreren Feldern sortieren. Wenn ein Projekt eine komplexe clientseitige Datenanalyse plant, ist Firestore die praktischere Wahl.
Realtime Database verwendet eine permanente WebSocket-Verbindung zur bidirektionalen Datensynchronisation. Wenn ein Client setValue oder updateChildren auf einem bestimmten Pfad aufruft, werden die Daten über den offenen Kanal an den Firebase-Server gesendet. Der Server wendet die Änderungen an und verteilt Aktualisierungen innerhalb von Millisekunden an alle abonnierten Clients. Jede Verbindung wird durch einen eindeutigen Sitzungsschlüssel identifiziert.
Der Abonnementmechanismus funktioniert über Listener. Ein Entwickler kann Änderungen an einem bestimmten Knoten abonnieren (addListenerForSingleValueEvent) oder kontinuierliche Aktualisierungen erhalten (addValueEventListener). Bei jeder Datenänderung wird der onDataChange-Callback mit einem vollständigen Daten-Snapshot des angegebenen Pfads ausgelöst. Dies unterscheidet sich von Firestore, wo nur geänderte Dokumente empfangen werden — in Realtime Database werden immer alle Knotendaten geladen.
Realtime Database unterstützt den Offline-Modus auf Android und iOS durch Disk-Caching. Das SDK behält eine lokale Kopie der Daten und verarbeitet Schreibvorgänge auch ohne Netzwerk weiter. Wenn die Verbindung wiederhergestellt wird, werden alle gesammelten Änderungen an den Server gesendet. Zur Konfliktlösung wird die Last-Write-Wins-Strategie verwendet, aber Entwickler können benutzerdefinierte Logik über ServerValue.TIMESTAMP zur Kollisionsauflösung implementieren.
val database = FirebaseDatabase.getInstance()
val myRef = database.getReference("messages")
// Datenschreiben
myRef.push().setValue(
hashMapOf(
"text" to "Neue Nachricht",
"timestamp" to ServerValue.TIMESTAMP
)
)
// Lesen mit kontinuierlichen Aktualisierungen
myRef.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val data = snapshot.getValue()
Log.d("TAG", "Daten: $data")
}
override fun onCancelled(error: DatabaseError) {
Log.w("TAG", "Fehler: ${error.message}")
}
})
Zur Optimierung von Traffic und Leistung wird empfohlen, beim Verfolgen von Änderungen an bestimmten untergeordneten Knoten Child-Listener anstelle von Value-Listenern zu verwenden. ChildEventListener bietet separate Callbacks zum Hinzufügen, Ändern, Entfernen und Verschieben von untergeordneten Elementen, was eine präzisere Steuerung von UI-Aktualisierungen ermöglicht und das Neuzeichnen aller Listenelemente bei jeder Datenänderung vermeidet.
Realtime Database verwendet eine deklarative Regelnsprache zur Datenzugriffskontrolle. Die Regeln beschreiben, wer Daten an jedem Pfad des JSON-Baums lesen und schreiben darf. Sie werden vor jeder Anfrage auf dem Firebase-Server überprüft und erfordern keine serverseitige Logik zur Autorisierung. Die Regeln unterstützen Variablen, integrierte Objekte und Funktionen für eine flexible Zugriffskonfiguration.
Standardmäßig ist der Datenbankzugriff für alle Benutzer verweigert. Der Entwickler öffnet nach und nach den Zugriff mit den Regeln ".read" und ".write" auf verschiedenen Baumebenen. Bedingungen können die Authentifizierung über die auth-Variable, den Anforderungstyp (Lesen/Schreiben) und vorhandene Daten über das data-Objekt überprüfen. Darüber hinaus unterstützen die Regeln die Validierung geschriebener Daten über das newData-Objekt.
{
"rules": {
"users": {
"$uid": {
// Nur der Besitzer kann seine Daten lesen
".read": "$uid === auth.uid",
// Nur der Besitzer kann schreiben
".write": "$uid === auth.uid",
// Feldvalidierung beim Schreiben
".validate": "newData.hasChildren(['name', 'email'])"
}
},
"messages": {
// Jeder authentifizierte Benutzer kann lesen
".read": "auth !== null",
// Nur authentifizierte Benutzer können schreiben
".write": "auth !== null",
".indexOn": ["timestamp"]
}
}
}
Die Regeln unterstützen auch die Datenindizierung über die ".indexOn"-Direktive. Ohne sie werden Abfragen mit Sortierung (orderByChild) abgelehnt oder ineffizient ausgeführt. Indizes werden für jeden Pfad angegeben, an dem eine Sortierung nach einem bestimmten Feld erfolgt. Die Regeln sind kaskadierend: tiefere Regeln überschreiben Elternregeln, und wenn auf einer Ebene kein Zugriff definiert ist, gilt er als erlaubt oder verweigert, abhängig von der Elternregel.
Realtime Database unterstützt fünf Datentypen: String, Number, Boolean, Map (Objekt) und List (Array). Die Verschachtelungstiefe ist auf 32 Ebenen begrenzt, und die maximale Größe eines einzelnen Knotens darf 256 MB nicht überschreiten. Für eine effiziente Datenbankarbeit wird empfohlen, eine flache Datenstruktur zu entwerfen und Denormalisierung zu verwenden, um tiefe Abfragen zu vermeiden, die große Datenmengen laden.
Betrachten wir ein praktisches Beispiel zur Integration von Realtime Database in eine Android-Anwendung für Benutzerstatus (online/offline). Die Anwendung zeigt eine Liste von Benutzern mit ihrem aktuellen Status an, der in Echtzeit aktualisiert wird. Zur Demonstration werden Firebase Authentication zur Benutzeridentifikation und Koroutinen für asynchrone Operationen verwendet.
Fügen Sie zunächst die Abhängigkeit firebase-database-ktx zur build.gradle-Datei des App-Moduls hinzu. Die Bibliotheksversion wird über Firebase BoM verwaltet, um die Kompatibilität aller Komponenten sicherzustellen. Nach dem Hinzufügen der Abhängigkeit muss Firebase in der Application-Klasse oder durch verzögerte Initialisierung im ViewModel initialisiert werden.
dependencies {
implementation platform("com.google.firebase:firebase-bom:33.0.0")
implementation "com.google.firebase:firebase-database-ktx"
implementation "com.google.firebase:firebase-auth-ktx"
}
Nach der Konfiguration wird ein Repository für die Arbeit mit Benutzern erstellt. Jeder Benutzer wird durch einen Knoten im Baum /users/{uid} mit den Feldern name, email und status dargestellt. Zur Statusverfolgung wird onDisconnect verwendet — ein spezieller Firebase-Mechanismus, der bei Unterbrechung der Client-Verbindung automatisch einen Schreibvorgang ausführt. Dadurch wird sichergestellt, dass der Benutzerstatus beim Schließen der App oder bei Netzwerkverlust ohne zusätzlichen Code auf dem Client auf "offline" wechselt.
class PresenceRepository {
private val database = FirebaseDatabase.getInstance()
private val auth = FirebaseAuth.getInstance()
private val presenceRef = database
.getReference("presence")
fun trackPresence() {
val uid = auth.currentUser?.uid ?: return
val userRef = presenceRef.child(uid)
userRef.onDisconnect().setValue("offline")
userRef.setValue("online")
}
fun getPresenceStream(): Flow<Map<String, String>> =
presenceRef.snapshotFlow()
.map { snapshot ->
(snapshot.value as? Map<*, *>)
?.mapKeys { it.key.toString() }
?.mapValues { it.value.toString() }
?: emptyMap()
}
}
Das Schlüsselelement des Beispiels ist onDisconnect. Dieser Mechanismus ermöglicht das Festlegen eines Schreibvorgangs, der auf dem Server ausgeführt wird, wenn die Client-Verbindung unterbrochen wird. In diesem Fall wird beim Trennen des Benutzers sein Status automatisch auf "offline" gesetzt, ohne dass das Schließen der App behandelt werden muss. Wenn die App abstürzt, führt Firebase selbst den onDisconnect-Vorgang aus, und andere Benutzer sehen den korrekten Status.
Häufig gestellte Fragen
Realtime Database speichert Daten in einem einzigen JSON-Baum und bietet eine niedrigere Synchronisationslatenz. Firestore verwendet Dokumentsammlungen, unterstützt komplexe Abfragen und starke Konsistenz. Realtime Database ist besser für einfache Chats und Statusmeldungen, Firestore für Anwendungen mit komplexen Datenstrukturen und Analysen.
Die maximale Größe eines einzelnen Realtime Database-Knotens beträgt 256 MB. Die Verschachtelungstiefe ist auf 32 Ebenen begrenzt. Für ein Firebase-Projekt können mehrere Realtime Database-Instanzen erstellt werden (bis zu 5 im Spark-Tarif und bis zu 100 im Blaze-Tarif), was eine Verteilung der Daten auf verschiedene Instanzen ermöglicht.
Realtime Database integriert sich mit Firebase Authentication. Die auth-Variable mit der UID des authentifizierten Benutzers ist in den Sicherheitsregeln verfügbar. Entwickler können den Zugriff auf einzelner Knotenebene des JSON-Baums einschränken, indem sie die UID des Datenbesitzers überprüfen. Anonyme und nicht authentifizierte Benutzer haben auth = null.
Ja, Realtime Database unterstützt Transaktionen über die runTransaction-Methode. Eine Transaktion garantiert die Atomizität des Lese-Änderungs-Schreib-Vorgangs für einen einzelnen Knoten. Bei gleichzeitigen Änderungen wird die Transaktion mit aktuellen Daten wiederholt. Dies ist nützlich für Zähler, Bewertungen und andere Szenarien, bei denen Datenkonsistenz wichtig ist.
Ja, Realtime Database unterstützt den Offline-Modus auf Android und iOS. Das SDK speichert Daten lokal zwischen und verarbeitet Schreibvorgänge ohne Netzwerk weiter. Bei Wiederherstellung der Verbindung werden alle gesammelten Änderungen mit dem Server synchronisiert. Zum Aktivieren des Offline-Modus verwenden Sie die Methode keepSynced(true) auf dem gewünschten Knoten.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch