Firebase Realtime DB — co to jest, architektura i praca z JSON

Autor: IT Sectr Opublikowano: 2026-03-12 Czas czytania: 10 min

Firebase Realtime Database — to chmurowa JSON-owa baza danych czasu rzeczywistego, uruchomiona przez Google w 2012 roku dla aplikacji mobilnych i webowych. Wszystkie dane są przechowywane w jednym dużym drzewie JSON i synchronizowane między podłączonymi klientami w czasie rzeczywistym przez połączenie WebSocket. Zgodnie z oficjalną dokumentacją Firebase, 2025, Realtime Database może obsługiwać do 200 000 jednoczesnych połączeń i obsługuje do 1000 jednoczesnych zapisów na sekundę. Baza danych nie wymaga infrastruktury serwerowej i udostępnia SDK dla iOS, Android, Web i platform serwerowych.

Najważniejsze

  • Firebase Realtime DB — chmurowa JSON-owa baza danych z synchronizacją danych między klientami w czasie rzeczywistym.
  • Dane są przechowywane w postaci jednego drzewa JSON, gdzie każdy węzeł jest dostępny przez unikalną ścieżkę.
  • Wbudowany tryb offline pozwala aplikacji działać bez internetu i synchronizować zmiany po przywróceniu połączenia.
  • Obsługuje do 200 000 jednoczesnych połączeń i do 1000 operacji zapisu na sekundę.
  • Integruje się z Firebase Authentication i niestandardowymi regułami bezpieczeństwa do kontroli dostępu do danych.

Czym jest Firebase Realtime Database?

Firebase Realtime Database — to chmurowa baza danych NoSQL, która przechowuje i synchronizuje dane w czasie rzeczywistym między wszystkimi podłączonymi klientami. Uruchomiona w 2012 roku jako Firebase (przed przejęciem przez Google), stała się pierwszą chmurową bazą czasu rzeczywistego dla programistów mobilnych. Dane są prezentowane w formacie JSON i zorganizowane w hierarchiczne drzewo, gdzie każdy węzeł ma unikalną ścieżkę.

Podstawowa wartość Realtime Database — wbudowana synchronizacja. Gdy aplikacja zmienia dane na dowolnym urządzeniu, wszyscy pozostali podłączeni klienci natychmiast otrzymują aktualizację przez stałe połączenie. To zwalnia programistę z implementacji własnego mechanizmu synchronizacji, serwera WebSocket lub REST API do przesyłania danych między klientami.

Baza danych udostępnia SDK dla wszystkich głównych platform: Android (Java, Kotlin), iOS (Swift, Objective-C), Web (JavaScript) i środowisk serwerowych przez Admin SDK. Według danych Google, Realtime Database jest używana w ponad 1,5 miliona aktywnych projektów Firebase na całym świecie. Mimo pojawienia się nowocześniejszej Firestore, Realtime Database pozostaje popularnym wyborem dla projektów z prostą strukturą danych.

Struktura danych: drzewo JSON

W przeciwieństwie do relacyjnych baz danych, Realtime Database nie używa tabel i wierszy. Wszystkie dane stanowią jedno drzewo JSON, które wygląda jak zagnieżdżone obiekty JavaScript. Na przykład, do przechowywania użytkowników i ich wiadomości tworzy się hierarchię: users/userId/name i messages/messageId/text. Każda ścieżka w drzewie to ciąg znaków, a dane można odczytywać bezpośrednio po tej ścieżce.

json
{
  "users": {
    "user1": {
      "name": "Iwan Pietrow",
      "email": "ivan@example.com"
    },
    "user2": {
      "name": "Maria Sokołowa",
      "email": "maria@example.com"
    }
  },
  "messages": {
    "-Nabc123": {
      "text": "Cześć!",
      "userId": "user1"
    }
  }
}

Ważną cechą jest to, że głębokie zagnieżdżenie wpływa na wydajność. Gdy aplikacja odczytuje dane po określonej ścieżce, ładuje wszystkie podrzędne węzły tej ścieżki. Dlatego zaleca się projektowanie struktury danych tak płaskiej, jak to możliwe, unikając zagnieżdżenia głębszego niż 3–4 poziomy. Aby obejść ten problem, stosuje się denormalizację danych — duplikowanie informacji w różnych węzłach drzewa.

Realtime Database vs Firestore: kiedy wybrać

Realtime Database i Firestore są często porównywane jako dwie chmurowe bazy czasu rzeczywistego od Google. Wybór między nimi zależy od konkretnych wymagań projektu: złożoności zapytań, wymaganej spójności i planowanego obciążenia. Zrozumienie mocnych stron każdej bazy pomaga podjąć właściwą decyzję architektoniczną.

Główną zaletą Realtime Database jest niskie opóźnienie synchronizacji. Ponieważ wszystkie dane są przechowywane w jednym drzewie JSON bez dodatkowych warstw abstrakcji, synchronizacja jest szybsza niż w Firestore. Dla aplikacji, w których szybkość dostarczania aktualizacji jest krytyczna (czaty, gry online, systemy wspólnego edytowania), Realtime Database może być bardziej odpowiednim wyborem.

Kiedy używać Realtime Database

Realtime Database lepiej nadaje się do scenariuszy z prostą strukturą danych i wysoką częstotliwością aktualizacji. Typowe przykłady: czaty, polubienia w czasie rzeczywistym, wskaźniki pisania, statusy obecności użytkowników. To także dobry wybór dla prototypów i projektów z ograniczonym budżetem, ponieważ cennik opiera się na ilości danych, a nie na liczbie operacji.

Z drugiej strony, dla aplikacji ze złożonymi zapytaniami (filtrowanie po wielu polach, sortowanie, agregacja) Firestore oferuje znacznie potężniejsze możliwości. Realtime Database obsługuje tylko filtrowanie po jednym parametrze i nie potrafi sortować wyników po wielu polach jednocześnie. Jeśli projekt planuje złożoną analitykę danych po stronie klienta, Firestore będzie bardziej praktycznym wyborem.

Jak działa synchronizacja w Realtime Database

Realtime Database używa stałego połączenia WebSocket do dwukierunkowej synchronizacji danych. Gdy klient wywołuje setValue lub updateChildren na określonej ścieżce, dane są wysyłane na serwer Firebase przez otwarty kanał. Serwer stosuje zmiany i rozsyła aktualizacje do wszystkich subskrybujących klientów w ciągu milisekund. Każde połączenie jest identyfikowane unikalnym kluczem sesji.

Mechanizm subskrypcji działa przez listenery. Programista może zasubskybować zmianę konkretnego węzła (addListenerForSingleValueEvent) lub otrzymywać stałe aktualizacje (addValueEventListener). Przy każdej zmianie danych wywoływany jest callback onDataChange z pełnym zrzutem danych po określonej ścieżce. Różni się to od Firestore, gdzie przychodzą tylko zmienione dokumenty — w Realtime Database zawsze ładowane są wszystkie dane węzła.

Tryb offline i zarządzanie konfliktami

Realtime Database obsługuje tryb offline na Android i iOS poprzez buforowanie dyskowe. SDK zapisuje lokalną kopię danych i kontynuuje przetwarzanie operacji zapisu przy braku sieci. Gdy połączenie zostanie przywrócone, wszystkie zgromadzone zmiany są wysyłane na serwer. Do rozwiązywania konfliktów używana jest strategia last-write-wins, ale programista może zaimplementować niestandardową logikę przez ServerValue.TIMESTAMP do rozwiązywania kolizji.

kotlin
val database = FirebaseDatabase.getInstance()
val myRef = database.getReference("messages")

// Zapis danych
myRef.push().setValue(
    hashMapOf(
        "text" to "Nowa wiadomość",
        "timestamp" to ServerValue.TIMESTAMP
    )
)

// Odczyt ze stałą aktualizacją
myRef.addValueEventListener(object : ValueEventListener {
    override fun onDataChange(snapshot: DataSnapshot) {
        val data = snapshot.getValue()
        Log.d("TAG", "Dane: $data")
    }

    override fun onCancelled(error: DatabaseError) {
        Log.w("TAG", "Błąd: ${error.message}")
    }
})

Dla optymalizacji ruchu i wydajności zaleca się używanie child listeners zamiast value listeners, gdy trzeba śledzić zmiany konkretnych węzłów podrzędnych. ChildEventListener udostępnia osobne callbacki dla dodawania, zmiany, usuwania i przenoszenia elementów podrzędnych, co pozwala precyzyjniej kontrolować aktualizacje UI i unikać przerysowywania wszystkich elementów listy przy każdej zmianie danych.

Zasady bezpieczeństwa i walidacja danych

Realtime Database używa deklaratywnego języka reguł do kontroli dostępu do danych. Reguły opisują, kto może czytać i zapisywać dane na każdej ścieżce drzewa JSON. Są one sprawdzane na serwerze Firebase przed każdym żądaniem i nie wymagają logiki serwerowej do autoryzacji. Reguły obsługują zmienne, wbudowane obiekty i funkcje do elastycznej konfiguracji dostępu.

Domyślnie dostęp do bazy danych jest zabroniony dla wszystkich użytkowników. Programista stopniowo otwiera dostęp, używając reguły ".read" i ".write" na różnych poziomach drzewa. Warunki mogą sprawdzać uwierzytelnienie przez zmienną auth, typ żądania (read/write) i istniejące dane przez obiekt data. Ponadto reguły obsługują walidację zapisywanych danych przez obiekt newData.

js
{
  "rules": {
    "users": {
      "$uid": {
        // Tylko właściciel może czytać swoje dane
        ".read": "$uid === auth.uid",
        // Tylko właściciel może pisać
        ".write": "$uid === auth.uid",
        // Walidacja pól przy zapisie
        ".validate": "newData.hasChildren(['name', 'email'])"
      }
    },
    "messages": {
      // Każdy uwierzytelniony może czytać
      ".read": "auth !== null",
      // Tylko uwierzytelniony może pisać
      ".write": "auth !== null",
      ".indexOn": ["timestamp"]
    }
  }
}

Reguły obsługują również indeksowanie danych przez dyrektywę ".indexOn". Bez niej zapytania z sortowaniem (orderByChild) zostaną odrzucone lub wykonane nieefektywnie. Indeksy są określanie dla każdej ścieżki, gdzie wykonywane jest sortowanie po określonym polu. Reguły są kaskadowe: głębsze reguły nadpisują nadrzędne, a jeśli na jakimś poziomie dostępu nie ma, jest on uznawany za dozwolony lub zabroniony w zależności od reguły nadrzędnej.

Typy danych i ograniczenia

Realtime Database obsługuje pięć typów danych: String, Number, Boolean, Map (obiekt) i List (tablica). Głębokość zagnieżdżenia jest ograniczona do 32 poziomów, a maksymalny rozmiar jednego węzła nie może przekraczać 256 MB. Dla efektywnej pracy z bazą zaleca się projektowanie płaskiej struktury danych i używanie denormalizacji, aby uniknąć głębokich zapytań ładujących duże ilości danych.

Przykład użycia Realtime Database w Android

Rozważmy praktyczny przykład integracji Realtime Database w aplikacji Android dla statusów użytkowników (online/offline). Aplikacja będzie wyświetlać listę użytkowników z ich bieżącym statusem, aktualizowanym w czasie rzeczywistym. Do demonstracji używane są Firebase Authentication do identyfikacji użytkowników i corutyny do operacji asynchronicznych.

Konfiguracja zależności i inicjalizacja

Na początek dodaj zależność firebase-database-ktx w pliku build.gradle modułu aplikacji. Wersja biblioteki jest zarządzana przez Firebase BoM w celu zapewnienia kompatybilności wszystkich komponentów. Po dodaniu zależności należy zainicjalizować Firebase w klasie Application lub przez leniwą inicjalizację w ViewModel.

groovy
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"
}

Po konfiguracji tworzony jest repozytorium do pracy z użytkownikami. Każdy użytkownik jest reprezentowany przez węzeł w drzewie /users/{uid} z polami name, email i status. Do śledzenia statusu używany jest onDisconnect — specjalny mechanizm Firebase, który automatycznie wykonuje operację zapisu przy zerwaniu połączenia klienta. Gwarantuje to, że status użytkownika zmieni się na "offline" przy zamknięciu aplikacji lub utracie sieci bez dodatkowego kodu po stronie klienta.

kotlin
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()
            }
}

Kluczowym elementem przykładu jest onDisconnect. Ten mechanizm pozwala ustawić operację zapisu, która zostanie wykonana na serwerze przy zerwaniu połączenia klienta. W tym przypadku przy odłączeniu użytkownika jego status jest automatycznie ustawiany na "offline" bez potrzeby obsługi zdarzenia zamknięcia aplikacji. Jeśli aplikacja zakończy się awaryjnie, Firebase sam wykona operację onDisconnect, a inni użytkownicy zobaczą poprawny status.

Często zadawane pytania

Jaka jest różnica między Firebase Realtime Database a Firestore?

Realtime Database przechowuje dane w jednym drzewie JSON i zapewnia niższe opóźnienie synchronizacji. Firestore używa kolekcji dokumentów, obsługuje złożone zapytania i silną spójność. Realtime Database jest lepsze do prostych czatów i statusów, Firestore — dla aplikacji ze złożoną strukturą danych i analityką.

Jaki jest maksymalny rozmiar danych w Realtime Database?

Maksymalny rozmiar jednego węzła Realtime Database wynosi 256 MB. Głębokość zagnieżdżenia jest ograniczona do 32 poziomów. Dla jednego projektu Firebase można utworzyć kilka baz danych Realtime Database (do 5 na planie Spark i do 100 na planie Blaze), co pozwala rozdzielić dane między różne instancje.

Jak działa uwierzytelnianie w Realtime Database?

Realtime Database integruje się z Firebase Authentication. W regułach bezpieczeństwa dostępna jest zmienna auth, zawierająca uid uwierzytelnionego użytkownika. Programista może rozgraniczać dostęp na poziomie poszczególnych węzłów drzewa JSON, sprawdzając zgodność uid właściciela danych. Anonimowi i nieuwierzytelnieni użytkownicy mają auth = null.

Czy Realtime Database obsługuje transakcje?

Tak, Realtime Database obsługuje transakcje przez metodę runTransaction. Transakcja gwarantuje atomowość operacji odczytu-zmiany-zapisu dla jednego węzła. Przy jednoczesnych zmianach transakcja jest powtarzana z aktualnymi danymi. Jest to przydatne dla liczników, ocen i innych scenariuszy, gdzie ważna jest spójność danych.

Czy można używać Realtime Database bez internetu?

Tak, Realtime Database obsługuje tryb offline na Android i iOS. SDK buforuje dane lokalnie i kontynuuje przetwarzanie operacji zapisu przy braku sieci. Po przywróceniu połączenia wszystkie zgromadzone zmiany są synchronizowane z serwerem. Do włączenia trybu offline używa się metody keepSynced(true) na odpowiednim węźle.

Podsumowanie

  • Firebase Realtime Database — chmurowa JSON-owa baza danych z synchronizacją między klientami w czasie rzeczywistym przez WebSocket.
  • Dane są przechowywane w drzewie JSON z hierarchiczną strukturą i dostępem przez unikalne ścieżki do każdego węzła.
  • Wbudowany tryb offline z buforowaniem dyskowym pozwala aplikacji działać bez połączenia z internetem.
  • Mechanizm onDisconnect automatycznie wykonuje operacje przy zerwaniu połączenia — idealny dla statusów obecności.
  • Zasady bezpieczeństwa i walidacja danych są konfigurowane deklaratywnie bez kodu serwerowego.
  • Cennik opiera się na ilości danych, a nie na liczbie operacji, co jest korzystne dla aplikacji z częstymi aktualizacjami.
  • Dla projektów z prostą strukturą danych i wymaganiami minimalnego opóźnienia Realtime Database pozostaje optymalnym wyborem.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również