Firebase Realtime Database — це хмарна NoSQL база даних Google із синхронізацією змін у реальному часі через постійне WebSocket-з'єднання. Дані зберігаються у вигляді єдиного JSON-дерева, і будь-яка зміна будь-якого вузла миттєво доставляється всім підключеним клієнтам. За даними Google, 2026, Realtime Database підтримує до 200 тисяч одночасних підключень до одного екземпляра. Сервіс надається з безкоштовним лімітом 1 ГБ сховища та 10 ГБ трафіку на місяць.
Головне
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 локально без підключення до хмари.
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 виконуються за допомогою фільтрів (orderByChild, orderByKey, orderByValue, limitToFirst, limitToLast, equalTo, startAt, endAt). На відміну від Firestore, індекси створюються вручну через розділ Rules (.indexOn). Якщо індекс не оголошений, запит із сортуванням повертає помилку PERMISSION_DENIED. Запити працюють лише по одному полю — складені запити (фільтр за ціною + сортування за датою) не підтримуються. Для складної фільтрації дані часто дублюються в різних вузлах з різними ключами сортування.
Вибір між Realtime Database та Firestore — одне з частих архітектурних рішень при старті проєкту. Google рекомендує Firestore для більшості нових застосунків, але 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-застосунку виконується додаванням залежності firebase-database-ktx у build.gradle. Об'єкт FirebaseDatabase доступний через getInstance(url) — можна підключитися до кількох баз у рамках одного проєкту Firebase. Після ініціалізації SDK автоматично встановлює WebSocket-з'єднання з сервером і починає синхронізацію даних.
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 при кожному оновленні даних.
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 — унікальна можливість 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 у режимі «закрито» — лише автентифіковані користувачі мають доступ.
Правила Realtime Database пишуться у форматі JSON з розділами .read, .write, .validate, .indexOn. На відміну від Firestore (який використовує match-синтаксис), Realtime Database використовує вкладені об'єкти, що повторюють структуру даних. Умови перевіряють auth (автентифікацію), data (існуючі дані), newData (нові дані при записі) та now (час сервера). Правила валідації (.validate) дозволяють перевіряти типи, діапазони значень та структуру даних.
{
"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"
}
}
}
}
Правила Realtime Database успадковуються каскадно — якщо на верхньому рівні .read = false, то всі дочірні вузли недоступні для читання незалежно від їхніх власних правил. Firebase надає симулятор правил у консолі, де можна протестувати операції з різними auth-токенами перед деплоєм. Рекомендується завжди тестувати rules у симуляторі — помилка в правилі може відкрити доступ до приватних даних усіх користувачів. За даними Google (2026), 40% витоків даних у Firebase-проєктах спричинені неправильно налаштованими правилами безпеки.
Часто задавані питання
До 200 тисяч одночасних підключень до одного екземпляра бази даних. При перевищенні ліміту нові підключення блокуються. Для масштабування використовується шардування на кілька баз.
Використовуйте onDisconnect — зареєструйте операцію запису «offline» при розриві з'єднання. Сервер автоматично виконає її при обриві WebSocket. Окремо відстежуйте підключення через .info/connected.
Перевірте .indexOn у Security Rules — без оголошеного індексу запит з orderByChild поверне PERMISSION_DENIED. Також переконайтеся, що дані записуються в правильний вузол і читач має права .read.
Firebase Console надає експорт з Realtime Database у Firestore однією кнопкою. JSON-структура перетворюється на колекції та документи. Для кастомної міграції використовуйте Admin SDK.
Ні, зберігати паролі у Realtime Database заборонено правилами безпеки Google. Використовуйте Firebase Auth для автентифікації — хеші паролів зберігаються в ізольованому сховищі, недоступному через Realtime Database SDK.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також