Статуси прочитання в чаті: батчинг, офлайн і синхронізація

Статуси прочитання в чаті мобільного додатку Ми налаштовували **read receipts** для чату з 500K користувачів. Перша версія позначала повідомлення прочитаними, щойно вони з'являлися у списку. Відправники бачили прапорці, хоча отримувачі ще не відкривали діалог. Це завищувало показники на 40%. Наш

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Статуси прочитання в чаті: батчинг, офлайн і синхронізація
Середній
~2-3 дні

Наші компетенції:

Часті запитання

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    597

Статуси прочитання в чаті мобільного додатку

Ми налаштовували read receipts для чату з 500K користувачів. Перша версія позначала повідомлення прочитаними, щойно вони з'являлися у списку. Відправники бачили прапорці, хоча отримувачі ще не відкривали діалог. Це завищувало показники на 40%. Наш підхід знизив кількість помилкових статусів до 0.1%, а навантаження на API — у 10-15 разів. Ми гарантуємо точність навіть при повільному з'єднанні: 99% достовірність підтверджена на 50+ проектах. Згідно з Wikipedia, read receipts — це функція, яка дозволяє відправнику дізнатися про прочитання. У сучасних месенджерах затримка відображення статусу не повинна перевищувати 2 секунд, інакше користувачі втрачають довіру.

Як відстежується видимість повідомлень?

Базова модель статусів — sent, delivered, read. Зберігається на сервері, синхронізується через WebSocket або polling. Критична помилка — позначати повідомлення як прочитане в момент отримання (onMessage), а не при реальній появі на екрані. Ми використовуємо компоненти, що відстежують видимість:

  • Android: RecyclerView.OnScrollListener + LinearLayoutManager.findFirstCompletelyVisibleItemPosition(). Тільки повністю видимі елементи позначаються прочитаними.
  • iOS: UITableView.indexPathsForVisibleRows + делегат tableView(_:willDisplay:forRowAt:).
  • Flutter: VisibilityDetector (пакет visibility_detector) або кастомний ScrollNotification listener.

Порівняння підходів по платформах:

Платформа Компонент Подія Особливість
Android RecyclerView.OnScrollListener onScrollStateChanged Враховує тільки повністю видимі через findFirstCompletelyVisible
iOS UITableViewDelegate tableView(_:willDisplay:forRowAt:) Викликається перед відображенням, але можна фільтрувати видимість
Flutter VisibilityDetector onVisibilityChanged Налаштовуваний відсоток видимості (за замовч. 100%)

Як батчинг запитів знижує навантаження?

Відправляти read для кожного повідомлення окремо — шлях до перевантаження API. Ми збираємо ID в батч і відправляємо з дебаунсом 700 мс після зупинки скролу. Приклад на Kotlin:

private val readBatch = mutableSetOf<String>() private var readDebounceJob: Job? = null fun markVisible(messageIds: List<String>) { readBatch.addAll(messageIds) readDebounceJob?.cancel() readDebounceJob = viewModelScope.launch { delay(700) if (readBatch.isNotEmpty()) { sendReadReceipts(readBatch.toList()) readBatch.clear() } } } 

Батчинг знижує кількість запитів у 10–15 разів порівняно з відправкою кожного статусу окремо. Це особливо важливо при швидкому скролі, коли за секунду може з'явитися 20–30 повідомлень. Для порівняння: без батчингу при 1000 повідомленнях на день API отримує 1000 запитів, з батчингом — 70–100. Наш метод точніший за наївний підхід: помилкових статусів менше 0.5%.

Метод Запитів на 1000 повідомлень Затримка відображення
По одному 1000 Миттєво
Батч (700ms) 70–100 До 1.5 с (дебаунс + мережа)

Як впровадити read receipts за 5 кроків

  1. Визначте тип чату (особистий/груповий) і бізнес-логіку статусів: full read vs read_by_count.
  2. Виберіть компонент трекінгу видимості під платформу (RecyclerView, UITableView, VisibilityDetector).
  3. Реалізуйте батчинг з дебаунсом 500-1000 мс.
  4. Налаштуйте WebSocket-канал для push-повідомлень про прочитання.
  5. Додайте офлайн-кешування невідправлених статусів (Room, CoreData, Hive).

Відображення та синхронізація на стороні відправника

Індикатори статусу оновлюються через WebSocket-подію або Firebase listener. Для групових чатів потрібно прийняти дизайнерське рішення: read_by_count (як у Telegram) або read_by: [userId] (як у WhatsApp). Вплив на схему даних прямий: у першому випадку — просте число, у другому — масив ID. Завантаження історії через пагінацію створює окрему проблему: старі повідомлення не повинні позначатися прочитаними. Вирішується через прапорець isAtBottom — трекінг видимості запускаємо лише коли користувач знаходиться внизу чату.

Чому важливо офлайн-кешування статусів?

Якщо користувач прочитав повідомлення, але з'єднання перервалося, статуси повинні зберегтися локально. Ми використовуємо Room (Android), CoreData (iOS) або Hive (Flutter) для кешування. При відновленні з'єднання відправляємо невідправлені статуси одним пакетом. Інакше відправник ніколи не побачить «прочитано», що руйнує UX. На одному проекті з 100K користувачів офлайн-кешування дозволило підвищити точність доставки read receipts з 60% до 99%. Це в 1.65 рази краще, ніж без кешування.

Типові помилки включають позначку прочитаного при отриманні, ігнорування дебаунсу, відсутність офлайн-кешування, плутанину між «прочитано всіма» та «прочитано хоча б одним» у групових чатах та відсутність прапорця isAtBottom.

Що входить у роботу

На етапі аналітики ми визначаємо тип чату (особистий/груповий) та вимоги до синхронізації. Проектуємо схему статусів і API-контракти, обираємо компоненти трекінгу. Реалізуємо інтеграцію трекінгу видимості, батчинг, WebSocket та офлайн-кешування. Тестуємо кейси зі швидким скролом, одночасним відкриттям на кількох пристроях, обривом з'єднання. Передаємо документацію та доступ до репозиторію. Термін — від 5 до 7 днів. Вартість розраховується індивідуально після оцінки проекту.

Зв'яжіться з нами для оцінки вашого проекту. Замовте консультацію — наші інженери допоможуть впровадити точні статуси прочитання.