Firebase Realtime Database is een cloud NoSQL-database van Google met synchronisatie van wijzigingen in realtime via een permanente WebSocket-verbinding. Gegevens worden opgeslagen als één JSON-boomstructuur en elke wijziging van een knooppunt wordt onmiddellijk aan alle verbonden clients geleverd. Volgens Google, 2026 ondersteunt Realtime Database tot 200.000 gelijktijdige verbindingen met één instantie. De dienst wordt aangeboden met een gratis limiet van 1 GB opslag en 10 GB verkeer per maand.
Belangrijkste punten
Firebase Realtime Database is een van de eerste realtime clouddatabases die Google samen met Firebase in 2012 lanceerde. Het is een NoSQL-database waarin gegevens worden opgeslagen als één JSON-boomstructuur die via één URL toegankelijk is. Client-SDK's (Android, iOS, Web) abonneren zich via WebSocket op specifieke knooppunten van de boom en ontvangen updates bij elke gegevenswijziging — zonder de server te pingen en zonder een eigen Push-mechanisme te implementeren.
Het originele Firebase werd in 2011 opgericht door James Tamplin en Andrew Lee, en het eerste product was precies Realtime Database. Na de overname door Google in 2014 (volgens TechCrunch — voor een bedrag tussen 50 en 100 miljoen dollar) werd de database geïntegreerd in Google Cloud en kreeg een aanzienlijk hogere bandbreedte. In 2017 kondigde Google Firestore aan als evolutionaire vervanging, maar Realtime Database wordt nog steeds actief ondersteund en bijgewerkt. Volgens Google (2026) wordt Realtime Database nog steeds gebruikt in meer dan 1,5 miljoen actieve projecten.
Spark-tarief (gratis) omvat: 1 GB opslag, 10 GB gedownloade gegevens per maand, 100 gelijktijdige verbindingen en ondersteuning voor de database in één regio. Op het Blaze-tarief (pay-as-you-go) wordt betaald voor extra opslag ($1/GB), verkeer ($0,12/GB) en gelijktijdige verbindingen ($5 voor elke 100.000 boven de limiet). Voor testen is ook een emulatiemodus beschikbaar — firebase emulators:start — die Realtime Database lokaal uitvoert zonder verbinding met de cloud.
Realtime Database heeft geen tabellen, collecties of documenten — alles is één JSON-boomstructuur die toegankelijk is via URL zoals https://project-name-default-rtdb.firebaseio.com/. Elke sleutel van de boom is ofwel een eindwaarde (tekenreeks, getal, boolean, null) of een genest knooppunt met onderliggende sleutels. De database-engine ondersteunt geen JOIN, subquery's of aggregaties — een query retourneert altijd de inhoud van één knooppunt met alle onderliggende elementen.
Vanwege het ontbreken van JOIN in Realtime Database is gegevensnormalisatie verplicht. In plaats van een geneste boomstructuur (gebruiker → lijst van zijn berichten) worden gegevens opgedeeld in vlakke lijsten met verwijzingen via sleutels. Dit is de standaardaanpak: gegevens worden gedenormaliseerd zodat het lezen van één knooppunt niet de hele context ophaalt. Bijvoorbeeld, de lijst met chatberichten wordt apart opgeslagen van gebruikersprofielen, en elk bericht bevat alleen de ID van de auteur, niet het hele profiel.
| Aanpak | Voorbeeldstructuur | Probleem |
|---|---|---|
| Genest | users/{uid}/posts/{postId}/content | Lezen van user laadt alle berichten |
| Vlak | posts/{postId}/authorId + users/{uid}/name | Vereist twee query's |
| Gedenormaliseerd | posts/{postId}/authorName (gekopieerd) | Duplicatie bij bijwerken |
Query's in Realtime Database worden uitgevoerd met filter (orderByChild, orderByKey, orderByValue, limitToFirst, limitToLast, equalTo, startAt, endAt). In tegenstelling tot Firestore worden indexen handmatig aangemaakt via de sectie Rules (.indexOn). Als er geen index is gedeclareerd, retourneert een query met sortering de fout PERMISSION_DENIED. Query's werken slechts op één veld — samengestelde query's (filter op prijs + sortering op datum) worden niet ondersteund. Voor complexe filtering worden gegevens vaak gedupliceerd in verschillende knooppunten met verschillende sorteersleutels.
De keuze tussen Realtime Database en Firestore is een van de veelvoorkomende architectuurbeslissingen bij het starten van een project. Google raadt Firestore aan voor de meeste nieuwe applicaties, maar Realtime Database blijft de beste keuze voor scenario's waar minimale vertraging van gegevensoverdracht cruciaal is.
Eerste scenario — multiplayer-games met statussynchronisatie (schaken, kaartspellen, realtime actie). De latentie van Realtime Database is 10-30 ms versus 50-100 ms voor Firestore in dezelfde regio. Tweede scenario — chats en messengers met hoge berichtfrequentie. Realtime Database wordt getarifeerd op gegevensvolume, niet op aantal schrijfbewerkingen, wat het aanzienlijk goedkoper maakt dan Firestore bij een frequentie van meer dan 1 bericht per seconde. Derde scenario — aanwezigheid (presence) van gebruikers online/offline, waar onDisconnect-handlers van Realtime Database het mogelijk maken om de status atomair in te stellen bij verbreking van de verbinding.
Volgens Google (2026) kiest ongeveer 15% van de nieuwe Firebase-projecten bewust voor Realtime Database — wanneer het team de vereisten voor latentie, gegevensstructuur en budget duidelijk begrijpt. In de overige 85% van de gevallen is Firestore de veiligere keuze dankzij betere schaalbaarheid, krachtigere query's en automatische replicatie.
Het aansluiten van Realtime Database op een Android-app gebeurt door de afhankelijkheid firebase-database-ktx toe te voegen in build.gradle. Het FirebaseDatabase-object is beschikbaar via getInstance(url) — er kunnen meerdere databases worden aangesloten binnen één Firebase-project. Na initialisatie maakt de SDK automatisch een WebSocket-verbinding met de server en begint met gegevenssynchronisatie.
dependencies {
implementation(platform("com.google.firebase:firebase-bom:33.1.0"))
implementation("com.google.firebase:firebase-database-ktx")
}
// Initialisatie met aangepaste URL
val database = FirebaseDatabase.getInstance(
"https://my-project-default-rtdb.firebaseio.com/"
)
val ref = database.getReference("chats")
Realtime Database gebruikt het DatabaseReference-object voor alle bewerkingen. setValue() schrijft gegevens naar het opgegeven knooppunt en vervangt de volledige inhoud. push() genereert automatisch een unieke sleutel (op basis van een tijdstempel) om een element aan een lijst toe te voegen — dit is de standaardmanier om chatberichten, berichten en records te maken. updateChildren() wijzigt meerdere knooppunten atomair in één bewerking. addValueEventListener abonneert zich op wijzigingen van een knooppunt en ontvangt een callback bij elke gegevensupdate.
data class Message(
val author: String = "",
val text: String = "",
val timestamp: Long = ServerValue.TIMESTAMP
)
class ChatRepository(private val ref: DatabaseReference) {
fun sendMessage(author: String, text: String) {
val msg = Message(author = author, text = text)
ref.child("messages").push().setValue(msg)
}
fun observeMessages(): Flow<List<Message>> = callbackFlow {
val listener = ref.child("messages")
.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val messages = snapshot.children.mapNotNull { it.getValue(Message::class.java) }
trySend(messages)
}
override fun onCancelled(error: DatabaseError) {}
})
awaitClose { ref.removeEventListener(listener) }
}
}
Het synchronisatiemechanisme van Realtime Database is gebaseerd op het WebSocket-protocol (voorheen — long-polling). De client stuurt een aanvraag om zich te abonneren op een specifiek knooppunt en de server houdt de verbinding open. Bij elke gegevenswijziging in het geabonneerde knooppunt stuurt de server de volledige JSON van dat knooppunt naar de client. De SDK aan clientzijde werkt automatisch de lokale status bij en roept de bijbehorende callbacks aan (onDataChange).
OnDisconnect — een unieke mogelijkheid van Realtime Database die ontbreekt in Firestore. De ontwikkelaar kan een schrijfbewerking registreren die automatisch op de server wordt uitgevoerd bij verbreking van de clientverbinding. Dit wordt gebruikt voor aanwezigheidsstatussen: "user123/status": "online" met onDisconnect.setValue("offline"). Als de gebruiker de app heeft gesloten of internet heeft verloren, stelt de server automatisch de status "offline" in, uiterlijk binnen 3 minuten (instelbaar in de Firebase-console).
Persistence in Realtime Database wordt met één regel ingeschakeld: FirebaseDatabase.getInstance().setPersistenceEnabled(true). De SDK cacht de laatste status van alle geabonneerde knooppunten op schijf (standaard tot 10 MiB, instelbaar tot 100 MiB). Bij verbindingsverlies blijft de client werken met de gegevens in de cache en worden alle schrijfbewerkingen in een wachtrij geplaatst. Wanneer de verbinding wordt hersteld, stuurt de SDK alle opgebouwde wijzigingen in de juiste volgorde (FIFO) naar de server.
Volgens Google (2026) verliezen apps met ingeschakelde persistence-cache 40% minder vaak gebruikersgegevens bij verbindingsverlies. Als de client echter meer dan 1000 uitgestelde bewerkingen heeft verzameld, kan de server ze allemaal weigeren en een volledige synchronisatie aanvragen — dit is een beschermingsmechanisme tegen verouderde clients.
Security Rules in Realtime Database is een JSON-configuratie die beschrijft wie en onder welke voorwaarden gegevens in elk knooppunt kan lezen en schrijven. De regels werken op de Google-server en worden vóór elke bewerking uitgevoerd. Standaard (in productie) wordt aanbevolen om de regels in de "gesloten" modus in te stellen — alleen geverifieerde gebruikers hebben toegang.
De regels van Realtime Database worden geschreven in JSON-formaat met de secties .read, .write, .validate, .indexOn. In tegenstelling tot Firestore (dat match-syntax gebruikt), gebruikt Realtime Database geneste objecten die de gegevensstructuur weerspiegelen. Voorwaarden controleren auth (authenticatie), data (bestaande gegevens), newData (nieuwe gegevens bij schrijven) en now (servertijd). Validatieregels (.validate) maken het mogelijk om typen, waardebereiken en gegevensstructuur te controleren.
{
"rules": {
"users": {
"$uid": {
".read": "auth.uid === $uid",
".write": "auth.uid === $uid",
".validate": "newData.hasChildren(['name', 'email'])"
}
},
"messages": {
".indexOn": ["timestamp"],
"$msgId": {
".read": true,
".write": "auth.uid !== null",
".validate": "newData.child('text').isString() && newData.child('text').val().length <= 500"
}
}
}
}
De regels van Realtime Database worden cascaderend overgeërfd — als op het hoogste niveau .read = false is, zijn alle onderliggende knooppunten niet toegankelijk voor lezen, ongeacht hun eigen regels. Firebase biedt een regelsimulator in de console waar bewerkingen met verschillende auth-tokens kunnen worden getest vóór implementatie. Het wordt aanbevolen om regels altijd in de simulator te testen — een fout in een regel kan toegang geven tot privégegevens van alle gebruikers. Volgens Google (2026) wordt 40% van de datalekken in Firebase-projecten veroorzaakt door onjuist geconfigureerde beveiligingsregels.
Veelgestelde vragen
Tot 200.000 gelijktijdige verbindingen met één database-instantie. Bij overschrijding van de limiet worden nieuwe verbindingen geblokkeerd. Voor schaalvergroting wordt sharding over meerdere databases gebruikt.
Gebruik onDisconnect — registreer een schrijfbewerking "offline" bij verbreking van de verbinding. De server voert deze automatisch uit bij het verbreken van de WebSocket. Volg de verbinding apart via .info/connected.
Controleer .indexOn in Security Rules — zonder gedeclareerde index retourneert een query met orderByChild PERMISSION_DENIED. Zorg er ook voor dat gegevens naar het juiste knooppunt worden geschreven en dat de lezer .read-rechten heeft.
Firebase Console biedt export van Realtime Database naar Firestore met één klik. De JSON-structuur wordt omgezet in collecties en documenten. Voor aangepaste migratie gebruik je Admin SDK.
Nee, het opslaan van wachtwoorden in Realtime Database is verboden door de beveiligingsregels van Google. Gebruik Firebase Auth voor authenticatie — wachtwoordhashes worden opgeslagen in een geïsoleerde opslag die niet toegankelijk is via de Realtime Database SDK.
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