Firebase Realtime Database е облачна NoSQL база данни на Google с синхронизация на промените в реално време чрез постоянна WebSocket връзка. Данните се съхраняват като единно JSON дърво и всяка промяна на който и да е възел незабавно се доставя на всички свързани клиенти. Според данни на Google, 2026, Realtime Database поддържа до 200 хиляди едновременни връзки към един екземпляр. Услугата се предоставя с безплатен лимит от 1 GB хранилище и 10 GB трафик на месец.
Основни точки
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 GB хранилище, 10 GB изтеглени данни на месец, 100 едновременни връзки и поддръжка на база данни в един регион. При Blaze тарифата (pay-as-you-go) се заплаща за допълнително хранилище ($1/GB), трафик ($0.12/GB) и едновременни връзки ($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 | Четенето на user зарежда всички публикации |
| Плосък | posts/{postId}/authorId + users/{uid}/name | Изисква две заявки |
| Денормализиран | posts/{postId}/authorName (копиран) | Дублиране при актуализация |
Заявките в Realtime Database се изпълняват с filter (orderByChild, orderByKey, orderByValue, limitToFirst, limitToLast, equalTo, startAt, endAt). За разлика от Firestore, индексите се създават ръчно чрез секцията Rules (.indexOn). Ако индексът не е деклариран, заявка със сортиране връща грешка PERMISSION_DENIED. Заявките работят само по едно поле — съставните заявки (филтър по цена + сортиране по дата) не се поддържат. За сложно филтриране данните често се дублират в различни възли с различни ключове за сортиране.
Изборът между Realtime Database и Firestore е едно от честите архитектурни решения при стартиране на проект. Google препоръчва Firestore за повечето нови приложения, но Realtime Database остава най-добрият избор за сценарии, където минималната латентност на предаване на данни е критична.
Първи сценарий — мултиплейър игри със синхронизация на състоянието (шах, карти, екшън в реално време). Латентността на Realtime Database е 10-30 ms срещу 50-100 ms за 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")
}
// Инициализация с персонализиран URL
val database = FirebaseDatabase.getInstance(
"https://my-project-default-rtdb.firebaseio.com/"
)
val ref = database.getReference("chats")
Realtime Database използва обекта DatabaseReference за всички операции. setValue() записва данни в указания възел, като напълно замества цялото му съдържание. push() автоматично генерира уникален ключ (на базата на времеви печат) за добавяне на елемент към списък — това е стандартният начин за създаване на чат съобщения, публикации и записи. updateChildren() променя множество възли атомарно в една операция. addValueEventListener се абонира за промени на възел и получава обратно извикване при всяка актуализация на данните.
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 от страна на клиента автоматично актуализира локалното състояние и извиква съответните обратни извиквания (onDataChange).
OnDisconnect — уникална възможност на Realtime Database, която липсва във Firestore. Разработчикът може да регистрира операция за запис, която ще се изпълни автоматично на сървъра при прекъсване на връзката на клиента. Това се използва за статуси на присъствие: "user123/status": "online" с onDisconnect.setValue("offline"). Ако потребителят е затворил приложението или е загубил интернет, сървърът автоматично ще зададе статус "offline" не по-късно от 3 минути (конфигурируемо в конзолата на Firebase).
Persistence в Realtime Database се активира с един ред: FirebaseDatabase.getInstance().setPersistenceEnabled(true). SDK кешира последното състояние на всички абонирани възли на диска (по подразбиране до 10 MiB, конфигурируемо до 100 MiB). При загуба на връзка клиентът продължава да работи с кеширани данни, а всички операции за запис се поставят на опашка. Когато връзката се възстанови, SDK изпраща всички натрупани промени на сървъра в правилния ред (FIFO).
Според данни на Google (2026), приложенията с активиран persistence кеш губят потребителски данни при прекъсване на връзката с 40% по-рядко. Ако обаче клиентът е натрупал повече от 1000 отложени операции, сървърът може да отхвърли всички и да поиска пълна синхронизация — това е защитен механизъм срещу остарели клиенти.
Security Rules в Realtime Database е JSON конфигурация, която описва кой и при какви условия може да чете и записва данни във всеки възел. Правилата работят на сървъра на Google и се изпълняват преди всяка операция. По подразбиране (в продукция) се препоръчва правилата да се настроят в режим "затворен" — само удостоверени потребители имат достъп.
Правилата на 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 токени преди внедряване. Препоръчва винаги да тествате правилата в симулатора — грешка в правило може да отвори достъп до частни данни на всички потребители. Според данни на 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 за удостоверяване — хешовете на паролите се съхраняват в изолирано хранилище, недостъпно чрез SDK на Realtime Database.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също