Firebase Realtime Database is een cloudgebaseerde JSON-realtime database, gelanceerd door Google in 2012 voor mobiele en webapplicaties. Alle gegevens worden opgeslagen in één grote JSON-boom en gesynchroniseerd tussen verbonden clients in realtime via een WebSocket-verbinding. Volgens de officiële documentatie Firebase, 2025, kan Realtime Database tot 200 000 gelijktijdige verbindingen en tot 1000 gelijktijdige schrijfbewerkingen per seconde aan. De database vereist geen serverinfrastructuur en biedt SDK's voor iOS, Android, Web en serverplatforms.
Belangrijkste punten
Firebase Realtime Database is een cloud NoSQL-database die gegevens in realtime opslaat en synchroniseert tussen alle verbonden clients. Gelanceerd in 2012 als Firebase (vóór de overname door Google), was het de eerste cloud-realtime database voor mobiele ontwikkelaars. Gegevens worden gepresenteerd in JSON-formaat en georganiseerd in een hiërarchische boom, waarbij elk knooppunt een uniek pad heeft.
De kernwaarde van Realtime Database is ingebouwde synchronisatie. Wanneer de app gegevens op een apparaat wijzigt, ontvangen alle andere verbonden clients onmiddellijk de update via een permanente verbinding. Dit bespaart de ontwikkelaar de implementatie van een eigen synchronisatiemechanisme, WebSocket-server of REST API voor gegevensoverdracht tussen clients.
De database biedt SDK's voor alle belangrijke platforms: Android (Java, Kotlin), iOS (Swift, Objective-C), Web (JavaScript) en serveromgevingen via Admin SDK. Volgens Google wordt Realtime Database gebruikt in meer dan 1,5 miljoen actieve Firebase-projecten wereldwijd. Ondanks de komst van de modernere Firestore, blijft Realtime Database een populaire keuze voor projecten met een eenvoudige gegevensstructuur.
In tegenstelling tot relationele databases gebruikt Realtime Database geen tabellen en rijen. Alle gegevens vormen één JSON-boom die eruitziet als geneste JavaScript-objecten. Bijvoorbeeld, voor het opslaan van gebruikers en hun berichten wordt een hiërarchie gecreëerd: users/userId/name en messages/messageId/text. Elk pad in de boom is een string en gegevens kunnen direct via dit pad worden gelezen.
{
"users": {
"user1": {
"name": "Ivan Petrov",
"email": "ivan@example.com"
},
"user2": {
"name": "Maria Sokolova",
"email": "maria@example.com"
}
},
"messages": {
"-Nabc123": {
"text": "Hallo!",
"userId": "user1"
}
}
}
Een belangrijke eigenschap is dat diepe nesting de prestaties beïnvloedt. Wanneer de app gegevens op een bepaald pad leest, laadt het alle onderliggende knooppunten van dat pad. Daarom wordt aanbevolen de gegevensstructuur zo plat mogelijk te ontwerpen, waarbij nesting dieper dan 3–4 niveaus wordt vermeden. Om dit probleem te omzeilen wordt denormalisatie van gegevens toegepast — het dupliceren van informatie in verschillende knooppunten van de boom.
Realtime Database en Firestore worden vaak vergeleken als twee cloud-realtime databases van Google. De keuze tussen hen hangt af van de specifieke projectvereisten: complexiteit van query's, vereiste consistentie en geplande belasting. Inzicht in de sterke punten van elke database helpt bij het nemen van de juiste architectuurbeslissing.
Het belangrijkste voordeel van Realtime Database is de lage synchronisatielatentie. Omdat alle gegevens in één JSON-boom zonder extra abstractielagen worden opgeslagen, is synchronisatie sneller dan in Firestore. Voor toepassingen waar de snelheid van het leveren van updates kritisch is (chats, online games, systemen voor gezamenlijke bewerking), kan Realtime Database de meer geschikte keuze zijn.
Realtime Database is geschikter voor scenario's met een eenvoudige gegevensstructuur en hoge updatefrequentie. Typische voorbeelden: chats, realtime likes, type-indicatoren, gebruikersaanwezigheidsstatussen. Het is ook een goede keuze voor prototypes en projecten met een beperkt budget, omdat de prijsstelling is gebaseerd op gegevensvolume, niet op het aantal bewerkingen.
Aan de andere kant biedt Firestore veel krachtigere mogelijkheden voor toepassingen met complexe query's (filteren op meerdere velden, sorteren, aggregatie). Realtime Database ondersteunt alleen filteren op één parameter en kan resultaten niet tegelijkertijd op meerdere velden sorteren. Als het project complexe gegevensanalyse aan de clientzijde plant, is Firestore de praktischere keuze.
Realtime Database gebruikt een permanente WebSocket-verbinding voor bidirectionele gegevenssynchronisatie. Wanneer de client setValue of updateChildren op een bepaald pad aanroept, worden de gegevens via een open kanaal naar de Firebase-server verzonden. De server past de wijzigingen toe en verspreidt de updates binnen milliseconden naar alle geabonneerde clients. Elke verbinding wordt geïdentificeerd door een unieke sessiesleutel.
Het abonnementsmechanisme werkt via listeners. De ontwikkelaar kan zich abonneren op wijzigingen van een specifiek knooppunt (addListenerForSingleValueEvent) of permanente updates ontvangen (addValueEventListener). Bij elke gegevenswijziging wordt de callback onDataChange aangeroepen met een volledige momentopname van de gegevens op het opgegeven pad. Dit verschilt van Firestore, waar alleen gewijzigde documenten binnenkomen — in Realtime Database worden altijd alle gegevens van het knooppunt geladen.
Realtime Database ondersteunt de offlinemodus op Android en iOS via schijfcaching. De SDK bewaart een lokale kopie van de gegevens en blijft schrijfbewerkingen verwerken bij afwezigheid van netwerk. Wanneer de verbinding wordt hersteld, worden alle opgebouwde wijzigingen naar de server verzonden. Voor het oplossen van conflicten wordt de last-write-wins-strategie gebruikt, maar de ontwikkelaar kan aangepaste logica implementeren via ServerValue.TIMESTAMP voor het oplossen van botsingen.
val database = FirebaseDatabase.getInstance()
val myRef = database.getReference("messages")
// Gegevens schrijven
myRef.push().setValue(
hashMapOf(
"text" to "Nieuw bericht",
"timestamp" to ServerValue.TIMESTAMP
)
)
// Lezen met constante update
myRef.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val data = snapshot.getValue()
Log.d("TAG", "Gegevens: $data")
}
override fun onCancelled(error: DatabaseError) {
Log.w("TAG", "Fout: ${error.message}")
}
})
Voor optimalisatie van verkeer en prestaties wordt aanbevolen child listeners te gebruiken in plaats van value listeners wanneer wijzigingen van specifieke onderliggende knooppunten moeten worden gevolgd. ChildEventListener biedt aparte callbacks voor het toevoegen, wijzigen, verwijderen en verplaatsen van onderliggende elementen, wat nauwkeurigere controle over UI-updates mogelijk maakt en het opnieuw tekenen van alle lijstelementen bij elke gegevenswijziging voorkomt.
Realtime Database gebruikt een declaratieve regeltaal voor toegangscontrole tot gegevens. De regels beschrijven wie gegevens op elk pad van de JSON-boom kan lezen en schrijven. Ze worden op de Firebase-server gecontroleerd vóór elk verzoek en vereisen geen serverlogica voor autorisatie. De regels ondersteunen variabelen, ingebouwde objecten en functies voor flexibele toegangsconfiguratie.
Standaard is toegang tot de database voor alle gebruikers verboden. De ontwikkelaar opent geleidelijk toegang met behulp van de regel ".read" en ".write" op verschillende niveaus van de boom. Voorwaarden kunnen authenticatie controleren via de variabele auth, het verzoektype (read/write) en bestaande gegevens via het data-object. Bovendien ondersteunen de regels validatie van geschreven gegevens via het newData-object.
{
"rules": {
"users": {
"$uid": {
// Alleen eigenaar kan eigen gegevens lezen
".read": "$uid === auth.uid",
// Alleen eigenaar kan schrijven
".write": "$uid === auth.uid",
// Validatie van velden bij schrijven
".validate": "newData.hasChildren(['name', 'email'])"
}
},
"messages": {
// Elke geverifieerde kan lezen
".read": "auth !== null",
// Alleen geverifieerde kan schrijven
".write": "auth !== null",
".indexOn": ["timestamp"]
}
}
}
De regels ondersteunen ook indexering van gegevens via de richtlijn ".indexOn". Zonder dit worden query's met sortering (orderByChild) afgewezen of inefficiënt uitgevoerd. Indexen worden gespecificeerd voor elk pad waar sortering op een bepaald veld wordt uitgevoerd. De regels zijn trapsgewijs: diepere regels overschrijven bovenliggende regels, en als op een bepaald niveau geen toegang is, wordt dit als toegestaan of verboden beschouwd afhankelijk van de bovenliggende regel.
Realtime Database ondersteunt vijf gegevenstypen: String, Number, Boolean, Map (object) en List (array). De nestdiepte is beperkt tot 32 niveaus en de maximale grootte van één knooppunt mag niet groter zijn dan 256 MB. Voor efficiënt werken met de database wordt aanbevolen een platte gegevensstructuur te ontwerpen en denormalisatie te gebruiken om diepe query's te voorkomen die grote hoeveelheden gegevens laden.
Laten we een praktisch voorbeeld bekijken van de integratie van Realtime Database in een Android-app voor gebruikersstatussen (online/offline). De app toont een lijst van gebruikers met hun huidige status, die in realtime wordt bijgewerkt. Voor de demonstratie worden Firebase Authentication gebruikt voor gebruikersidentificatie en coroutines voor asynchrone bewerkingen.
Voeg om te beginnen de afhankelijkheid firebase-database-ktx toe aan het build.gradle-bestand van de app-module. De bibliotheekversie wordt beheerd via Firebase BoM om compatibiliteit van alle componenten te garanderen. Na het toevoegen van de afhankelijkheid moet Firebase worden geïnitialiseerd in de Application-klasse of via luie initialisatie in de ViewModel.
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"
}
Na configuratie wordt een repository gemaakt voor het werken met gebruikers. Elke gebruiker wordt vertegenwoordigd door een knooppunt in de /users/{uid}-boom met velden name, email en status. Voor het volgen van de status wordt onDisconnect gebruikt — een speciaal Firebase-mechanisme dat automatisch een schrijfbewerking uitvoert bij verbreking van de clientverbinding. Dit garandeert dat de gebruikersstatus verandert naar "offline" bij het sluiten van de app of netwerkverlies zonder extra code aan de clientzijde.
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()
}
}
Het sleutelelement van het voorbeeld is onDisconnect. Dit mechanisme maakt het mogelijk een schrijfbewerking in te stellen die op de server wordt uitgevoerd bij verbreking van de clientverbinding. In dit geval wordt bij het loskoppelen van de gebruiker zijn status automatisch ingesteld op "offline" zonder dat de gebeurtenis van het sluiten van de app hoeft te worden afgehandeld. Als de app onverwacht wordt afgesloten, voert Firebase zelf de onDisconnect-bewerking uit en zien andere gebruikers de juiste status.
Veelgestelde vragen
Realtime Database slaat gegevens op in één JSON-boom en biedt een lagere synchronisatielatentie. Firestore gebruikt documentcollecties, ondersteunt complexe query's en sterke consistentie. Realtime Database is beter voor eenvoudige chats en statussen, Firestore — voor apps met complexe gegevensstructuur en analyse.
De maximale grootte van één knooppunt in Realtime Database is 256 MB. De nestdiepte is beperkt tot 32 niveaus. Voor één Firebase-project kunnen meerdere Realtime Database-databases worden gemaakt (tot 5 op het Spark-plan en tot 100 op het Blaze-plan), waardoor gegevens over verschillende instanties kunnen worden verdeeld.
Realtime Database integreert met Firebase Authentication. In de beveiligingsregels is de variabele auth beschikbaar, die de uid van de geverifieerde gebruiker bevat. De ontwikkelaar kan de toegang beperken op het niveau van individuele knooppunten van de JSON-boom door de overeenkomst van de uid van de gegevenseigenaar te controleren. Anonieme en niet-geverifieerde gebruikers hebben auth = null.
Ja, Realtime Database ondersteunt transacties via de methode runTransaction. Een transactie garandeert atomiciteit van de lees-wijzig-schrijf-bewerking voor één knooppunt. Bij gelijktijdige wijzigingen wordt de transactie herhaald met actuele gegevens. Dit is nuttig voor tellers, beoordelingen en andere scenario's waar gegevensconsistentie belangrijk is.
Ja, Realtime Database ondersteunt de offlinemodus op Android en iOS. De SDK cached gegevens lokaal en blijft schrijfbewerkingen verwerken bij afwezigheid van netwerk. Na herstel van de verbinding worden alle opgebouwde wijzigingen met de server gesynchroniseerd. Voor het inschakelen van de offlinemodus wordt de methode keepSynced(true) op het betreffende knooppunt gebruikt.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook