Firebase Realtime Database: шта је то, JSON структура и синхронизација

Аутор: IT Sectr Објављено: 2026-04-28 Време читања: 10 мин

Firebase Realtime Database је облачна NoSQL база података компаније Google са синхронизацијом промена у реалном времену преко сталне WebSocket везе. Подаци се чувају као јединствено JSON стабло, а свака промена било ког чвора се тренутно доставља свим повезаним клијентима. Према подацима Google, 2026, Realtime Database подржава до 200 хиљада истовремених веза са једном инстанцом. Услуга се пружа са бесплатним лимитом од 1 GB простора и 10 GB саобраћаја месечно.

Главне тачке

  • 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 GB простора, 10 GB преузетих података месечно, 100 истовремених веза и подршку за базу података у једном региону. На Blaze тарифи (pay-as-you-go) наплаћује се додатни простор (1 $/GB), саобраћај (0,12 $/GB) и истовремене везе (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Читање user учитава све објаве
Равниposts/{postId}/authorId + users/{uid}/nameЗахтева два упита
Денормализованиposts/{postId}/authorName (копиран)Дуплирање при ажурирању

Упити у Realtime Database

Упити у Realtime Database извршавају се помоћу filter (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 ms у поређењу са 50-100 ms за 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")
}

// Иницијализација са прилагођеним URL-ом
val database = FirebaseDatabase.getInstance(
    "https://my-project-default-rtdb.firebaseio.com/"
)
val ref = database.getReference("chats")

Упис и читање података

Realtime Database користи објекат DatabaseReference за све операције. setValue() уписује податке у наведени чвор, потпуно замењујући сав његов садржај. push() аутоматски генерише јединствени кључ (на основу временске ознаке) за додавање елемента у листу — ово је стандардни начин креирања порука ћаскања, објава и записа. updateChildren() мења више чворова атомски у једној операцији. addValueEventListener се претплаћује на промене чвора и добија повратни позив при сваком ажурирању података.

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 на клијентској страни аутоматски ажурира локално стање и позива одговарајуће повратне позиве (onDataChange).

OnDisconnect — окидачи искључења

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) омогућавају проверу типова, опсега вредности и структуре података.

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

Каскадно понашање и тестирање правила

Правила Realtime Database-а наслеђују се каскадно — ако на горњем нивоу .read = false, сви подређени чворови су недоступни за читање без обзира на њихова сопствена правила. Firebase обезбеђује симулатор правила у конзоли где се могу тестирати операције са различитим auth токенима пре примене. Препоручује се увек тестирати правила у симулатору — грешка у правилу може отворити приступ приватним подацима свих корисника. Према подацима 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 — јединствени механизам за атомски упис статуса присуства при прекиду везе клијента.
  • SMS верификација и офлајн кеш до 10 MiB са редом операција омогућавају апликацији да ради без интернета и синхронизује се при успостављању везе.
  • Security Rules — каскадни систем права приступа са подршком за валидацију типова и вредности преко .validate.
  • Препоручује се за игре, ћаскања и presence сценарије — апликације критичне за минимално кашњење преноса података.
  • Цене се заснивају на обиму простора, преузетом саобраћају и истовременим везама, а не на броју операција као у Firestore-у.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође