Firebase Realtime Database: що це таке, структура JSON та синхронізація

Автор: IT Sectr Опубліковано: 2026-04-28 Час читання: 10 хв

Firebase Realtime Database — це хмарна NoSQL база даних Google із синхронізацією змін у реальному часі через постійне WebSocket-з'єднання. Дані зберігаються у вигляді єдиного JSON-дерева, і будь-яка зміна будь-якого вузла миттєво доставляється всім підключеним клієнтам. За даними Google, 2026, Realtime Database підтримує до 200 тисяч одночасних підключень до одного екземпляра. Сервіс надається з безкоштовним лімітом 1 ГБ сховища та 10 ГБ трафіку на місяць.

Головне

  • Firebase Realtime Database — хмарне JSON-дерево з синхронізацією змін у реальному часі через WebSocket.
  • Дані доступні офлайн — SDK кешує останній стан і синхронізується при відновленні з'єднання.
  • Підтримує до 200 тисяч одночасних підключень до одного екземпляра бази даних.
  • Структура даних — єдине JSON-дерево, що спрощує читання, але потребує плоскої нормалізації для продуктивності.
  • Ціноутворення базується на обсязі даних і кількості одночасних з'єднань, а не на кількості операцій.

Що таке Firebase Realtime Database

Firebase Realtime Database — одна з перших хмарних баз даних у реальному часі, запущена Google разом із Firebase у 2012 році. Це NoSQL база, де дані зберігаються як єдине JSON-дерево, доступне через один URL. Клієнтські SDK (Android, iOS, Web) підписуються на конкретні вузли дерева через WebSocket і отримують оновлення при кожній зміні даних — без опитування сервера та без реалізації власного Push-механізму.

Історія та розвиток

Оригінальна Firebase була заснована у 2011 році Джеймсом Темпліном та Ендрю Лі, а першим продуктом стала саме Realtime Database. Після придбання Google у 2014 році (за даними TechCrunch — на суму від 50 до 100 мільйонів доларів) база була інтегрована в Google Cloud і отримала значно вищу пропускну здатність. У 2017 році Google анонсувала Firestore як еволюційну заміну, але Realtime Database продовжує активно підтримуватися та оновлюватися. За даними Google (2026), Realtime Database досі використовується в більш ніж 1,5 мільйонах активних проєктів.

Безкоштовні ліміти та тарифи

Spark-тариф (безкоштовний) включає: 1 ГБ сховища, 10 ГБ завантажених даних на місяць, 100 одночасних підключень і підтримку бази даних в одному регіоні. На Blaze-тарифі (pay-as-you-go) плата стягується за додаткове сховище ($1/ГБ), трафік ($0.12/ГБ) та одночасні з'єднання ($5 за кожні 100 тисяч понад ліміт). Для тестування також доступний режим емуляції — firebase emulators:start — який запускає Realtime Database локально без підключення до хмари.

Структура даних: JSON-дерево та нормалізація

Realtime Database не має таблиць, колекцій чи документів — все являє собою одне JSON-дерево, доступне за URL виду https://project-name-default-rtdb.firebaseio.com/. Кожен ключ дерева — це або кінцеве значення (рядок, число, boolean, null), або вкладений вузол з дочірніми ключами. Рушій бази не підтримує JOIN, підзапити чи агрегації — запит завжди повертає вміст одного вузла з усіма дочірніми елементами.

Нормалізація даних

Через відсутність JOIN у Realtime Database нормалізація даних є обов'язковою. Замість вкладеного дерева (користувач → список його дописів) дані розбиваються на плоскі списки з посиланнями через ключі. Це стандартний підхід: дані денормалізуються, щоб читання одного вузла не витягувало весь контекст. Наприклад, список повідомлень чату зберігається окремо від профілів користувачів, а кожен допис містить лише ID автора, а не весь його профіль.

ПідхідПриклад структуриПроблема
Вкладенийusers/{uid}/posts/{postId}/contentЧитання користувача завантажує всі дописи
Плоскийposts/{postId}/authorId + users/{uid}/nameПотрібно два запити
Денормалізованийposts/{postId}/authorName (скопійовано)Дублювання при оновленні

Запити в Realtime Database

Запити в Realtime Database виконуються за допомогою фільтрів (orderByChild, orderByKey, orderByValue, limitToFirst, limitToLast, equalTo, startAt, endAt). На відміну від Firestore, індекси створюються вручну через розділ Rules (.indexOn). Якщо індекс не оголошений, запит із сортуванням повертає помилку PERMISSION_DENIED. Запити працюють лише по одному полю — складені запити (фільтр за ціною + сортування за датою) не підтримуються. Для складної фільтрації дані часто дублюються в різних вузлах з різними ключами сортування.

Realtime Database vs Firestore: що вибрати

Вибір між Realtime Database та Firestore — одне з частих архітектурних рішень при старті проєкту. Google рекомендує Firestore для більшості нових застосунків, але Realtime Database залишається найкращим вибором для сценаріїв, де критичною є мінімальна затримка передачі даних.

Три ключові сценарії для Realtime Database

Перший сценарій — багатокористувацькі ігри з синхронізацією стану (шахи, карткові ігри, екшн у реальному часі). Затримка Realtime Database становить 10-30 мс проти 50-100 мс у Firestore в одному регіоні. Другий сценарій — чати та месенджери з високою частотою повідомлень. Realtime Database тарифікується за обсягом даних, а не за кількістю записів, що робить його значно дешевшим за Firestore при частоті понад 1 повідомлення на секунду. Третій сценарій — присутність (presence) користувачів онлайн/офлайн, де onDisconnect-обробники Realtime Database дозволяють атомарно встановити статус при обриві з'єднання.

За даними Google (2026), приблизно 15% нових проєктів Firebase обирають Realtime Database свідомо — коли команда чітко розуміє вимоги до затримки, структури даних та бюджету. В решті 85% випадків Firestore є безпечнішим вибором завдяки кращій масштабованості, потужнішим запитам та автоматичній реплікації.

Інтеграція Realtime Database в Android

Підключення Realtime Database до Android-застосунку виконується додаванням залежності firebase-database-ktx у build.gradle. Об'єкт FirebaseDatabase доступний через getInstance(url) — можна підключитися до кількох баз у рамках одного проєкту Firebase. Після ініціалізації SDK автоматично встановлює WebSocket-з'єднання з сервером і починає синхронізацію даних.

groovy
dependencies {
    implementation(platform("com.google.firebase:firebase-bom:33.1.0"))
    implementation("com.google.firebase:firebase-database-ktx")
}

// Initialization with custom URL
val database = FirebaseDatabase.getInstance(
    "https://my-project-default-rtdb.firebaseio.com/"
)
val ref = database.getReference("chats")

Запис та читання даних

Realtime Database використовує об'єкт DatabaseReference для всіх операцій. setValue() записує дані у вказаний вузол, повністю замінюючи весь його вміст. push() автоматично генерує унікальний ключ (на основі часової мітки) для додавання елемента до списку — це стандартний спосіб створення повідомлень чату, дописів та записів. updateChildren() змінює кілька вузлів атомарно за одну операцію. addValueEventListener підписується на зміни вузла та отримує callback при кожному оновленні даних.

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

Синхронізація в реальному часі та офлайн-режим

Механізм синхронізації Realtime Database базується на протоколі WebSocket (раніше — long-polling). Клієнт надсилає запит на підписку до певного вузла, а сервер утримує з'єднання відкритим. При будь-якій зміні даних у підписаному вузлі сервер надсилає клієнту повний JSON цього вузла. SDK на клієнті автоматично оновлює локальний стан та викликає відповідні callback-и (onDataChange).

OnDisconnect — тригери відключення

OnDisconnect — унікальна можливість Realtime Database, відсутня у Firestore. Розробник може зареєструвати операцію запису, яка виконається на сервері автоматично при розриві з'єднання клієнта. Це використовується для статусів присутності: «user123/status»: «online» з onDisconnect.setValue(«offline»). Якщо користувач закрив застосунок або втратив інтернет, сервер автоматично встановить статус «offline» не пізніше ніж через 3 хвилини (налаштовується в консолі Firebase).

Офлайн-кеш

Persistence у Realtime Database вмикається одним рядком: FirebaseDatabase.getInstance().setPersistenceEnabled(true). SDK кешує останній стан всіх підписаних вузлів на диску (до 10 МіБ за замовчуванням, налаштовується до 100 МіБ). При втраті з'єднання клієнт продовжує працювати з кешованими даними, а всі операції запису ставляться в чергу. Коли з'єднання відновлюється, SDK надсилає всі накопичені зміни на сервер у правильному порядку (FIFO).

За даними Google (2026), застосунки з увімкненим persistence-кешем на 40% рідше втрачають дані користувачів при обриві з'єднання. Однак якщо клієнт накопичив більше 1000 відкладених операцій, сервер може відхилити їх усі та запитати повну синхронізацію — це захисний механізм проти застарілих клієнтів.

Правила безпеки та валідація

Security Rules у Realtime Database — це JSON-конфігурація, що описує, хто і за яких умов може читати та писати дані в кожному вузлі. Правила працюють на сервері Google і виконуються до кожної операції. За замовчуванням (у production) рекомендується встановлювати rules у режимі «закрито» — лише автентифіковані користувачі мають доступ.

Структура rules

Правила Realtime Database пишуться у форматі JSON з розділами .read, .write, .validate, .indexOn. На відміну від Firestore (який використовує match-синтаксис), Realtime Database використовує вкладені об'єкти, що повторюють структуру даних. Умови перевіряють auth (автентифікацію), data (існуючі дані), newData (нові дані при записі) та now (час сервера). Правила валідації (.validate) дозволяють перевіряти типи, діапазони значень та структуру даних.

javascript
{
  "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"
      }
    }
  }
}

Каскадна поведінка та тестування rules

Правила Realtime Database успадковуються каскадно — якщо на верхньому рівні .read = false, то всі дочірні вузли недоступні для читання незалежно від їхніх власних правил. Firebase надає симулятор правил у консолі, де можна протестувати операції з різними auth-токенами перед деплоєм. Рекомендується завжди тестувати rules у симуляторі — помилка в правилі може відкрити доступ до приватних даних усіх користувачів. За даними Google (2026), 40% витоків даних у Firebase-проєктах спричинені неправильно налаштованими правилами безпеки.

Часто задавані питання

Скільки одночасних підключень витримує Realtime Database?

До 200 тисяч одночасних підключень до одного екземпляра бази даних. При перевищенні ліміту нові підключення блокуються. Для масштабування використовується шардування на кілька баз.

Як реалізувати присутність користувачів онлайн/офлайн?

Використовуйте onDisconnect — зареєструйте операцію запису «offline» при розриві з'єднання. Сервер автоматично виконає її при обриві WebSocket. Окремо відстежуйте підключення через .info/connected.

Чому мої запити не повертають дані?

Перевірте .indexOn у Security Rules — без оголошеного індексу запит з orderByChild поверне PERMISSION_DENIED. Також переконайтеся, що дані записуються в правильний вузол і читач має права .read.

Як перенести дані з Realtime Database у Firestore?

Firebase Console надає експорт з Realtime Database у Firestore однією кнопкою. JSON-структура перетворюється на колекції та документи. Для кастомної міграції використовуйте Admin SDK.

Чи безпечна Realtime Database для зберігання паролів?

Ні, зберігати паролі у Realtime Database заборонено правилами безпеки Google. Використовуйте Firebase Auth для автентифікації — хеші паролів зберігаються в ізольованому сховищі, недоступному через Realtime Database SDK.

Підсумки

  • Firebase Realtime Database — NoSQL JSON-дерево з синхронізацією в реальному часі через WebSocket, представлене Google у 2012 році.
  • Дані нормалізуються в плоскі списки з посиланнями за ключами через відсутність JOIN та підтримки складних запитів.
  • OnDisconnect — унікальний механізм для атомарного запису статусу присутності при обриві з'єднання клієнта.
  • Офлайн-кеш до 10 МіБ з чергою операцій дозволяє застосунку працювати без інтернету та синхронізуватися при відновленні.
  • Security Rules — каскадна система прав доступу з підтримкою валідації типів та значень через .validate.
  • Рекомендована для ігор, чатів та presence-сценаріїв — застосунків, критичних до мінімальної затримки передачі даних.
  • Ціноутворення базується на обсязі сховища, завантаженого трафіку та одночасних з'єднаннях, а не на кількості операцій як у Firestore.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також