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Чтение 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

Первый сценарий — многопользовательские игры с синхронизацией состояния (шахматы, карточные игры, action в реальном времени). Задержка 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")
}

// Инициализация с кастомным 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"
      }
    }
  }
}

Cascade behaviour и тестирование 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 — уникальный механизм для атомарной записи статуса присутствия при обрыве соединения клиента.
  • SMS-верификация и офлайн-кэш до 10 МиБ с очередью операций позволяют приложению работать без интернета и синхронизироваться при восстановлении.
  • Security Rules — каскадная система прав доступа с поддержкой валидации типов и значений через .validate.
  • Рекомендована для игр, чатов и presence-сценариев — приложений, критичных к минимальной задержке передачи данных.
  • Ценообразование базируется на объёме хранилища, скачанного трафика и одновременных соединений, а не на количестве операций как в Firestore.

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

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