Розробка групового чату в мобільному додатку

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Розробка групового чату в мобільному додатку
Складний
від 1 тижня до 3 місяців
Часті запитання

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

Етапи розробки

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

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Розробка групового чата в мобільному додатку

Груповий чат складніший за приватний не в рази, а на порядок. У приватному чаті два учасники — всі события синхронізуються через одне WebSocket-з'єднання до однієї conversation. У груповому чаті на 200 учасників сервер повинен fanout кожного повідомлення в 199 з'єднань, правильно вичислювати непрочитані для кожного, не давити Redis під навантаженням та коректно працювати коли частина учасників офлайн. Це вже проблема архітектури, а не просто UI.

Серверна архітектура: fanout та presences

Розподіл повідомлень

Найболюча частина — доставка повідомлення всім учасникам групи. Синхронний fanout («відправили → прогнали по всім з'єднанням → відповідили клієнту») не масштабується: при групі на 500 людей ітерація по активним з'єднанням займає десятки мілісекунд, а якщо WS-серверів кілька — з'єднання учасників розподілені по різних нодах.

Правильна схема: клієнт → WebSocket-сервер → черга (Redis Pub/Sub або Kafka topic per group) → кожен WS-сервер читає з своєї черги та доставляє онлайн-учасникам → для офлайн-учасників — черга push-сповіщень.

Для груп до 100 учасників Redis Pub/Sub з channel-per-group працює добре. Для більших — Kafka або NATS JetStream з consumer groups.

Непрочитані повідомлення (unread counts)

Класична помилка — зберігати last_read_message_id у таблиці group_members та при кожному запиті рахувати SELECT COUNT(*) WHERE id > last_read_message_id. На групі з тисячами повідомлень та сотнями учасників це вбиває базу.

Робочий підхід: Redis Hash unread:{user_id}:{group_id} → інкремент на кожне нове повідомлення в групі, reset при відкритті чата. Суммарний badge — HVALS unread:{user_id} та суммування на клієнті. При перезапуску Redis — пересчет з PostgreSQL як fallback.

Ролі та права

Схема: owner, admin, member. Права гранулярно: can_send_messages, can_add_members, can_remove_members, can_edit_group_info. Зберігається в group_members.role + JSON-поле permissions для кастомних переопередень. Проверка на рівні API middleware до виконання action.

Мобільний UI: що технічно складно

Список учасників та упоминання

При вводі @ — popup з фільтрацією учасників. На iOS: UITextView + кастомний UIView-overlay позиціонований над клавіатурою через KeyboardLayoutGuide. При виборі учасника — вставка атрибутованої рядка з NSAttributedString та кастомним NSTextAttachment або просто кольоровий range.

У Jetpack Compose: BasicTextField з кастомним VisualTransformation для окраски упоминань + Popup з LazyColumn для выпадающого списку. Тригер @ — через TextFieldValue.text.lastIndexOf('@') з debounce 200ms.

На бекі при збереженні повідомлення — парсинг упоминань регуляркою, створення message_mentions[] записів, окремий push-сповіщення упомянутим учасникам навіть якщо вони відключили сповіщення групи.

Медіа та файли в групі

Фото, відео, документи — завантаження через presigned S3 URL як у приватному чаті, але з додатковою проверкою квот (ліміт хранилища на групу або на користувача). Медіагалерея групи — окремий екран з UICollectionView/LazyVerticalGrid, выборка з таблиці messages по type IN ('image','video') AND group_id = ? з пагінацією.

Превью посилань (link preview): на сервері при отриманні повідомлення з URL — асинхронний job (Sidekiq/Celery) парсит Open Graph метадані, кешує в Redis на 24h, клієнт отримує дані превю в событії message.updated.

Індикатор набору тексту

WS-event typing.start / typing.stop від клієнта → сервер рассилає в групу з user_id печатающого → клієнти показують «Іван набирає...». Проблема: при 20 одночасно набираючих учасниках UX ломається. Обмеження: показуємо максимум 3 імені, далі «і ще N людей набирають». Таймаут: якщо typing.stop не прийшов — автоматично скриваємо через 5 секунд.

Офлайн та синхронізація

Груповий чат вимагає локальної БД. SQLite через SQLCipher (шифрування) — схема: groups, messages, group_members. При старті додатку — sync з сервером: запит всіх груп з last_synced_at, потім для кожної групи — повідомлення після останнього message_id. Конфлікти при одночасному редагуванні — Last Write Wins по updated_at.

На iOS — GRDB.swift поверх SQLite, на Android — Room з Flow-підпиской для реактивного оновлення UI.

Типічні помилки при самостійній реалізації

  • N+1 при завантаженні списку груп: для кожної групи окремий запит last_message. Рішення: JOIN з підзапитом або денормалізоване поле last_message_preview.
  • Push на всі повідомлення без урахування mute: учасник заглушив групу, але отримує пуш. Проверка group_members.notifications_muted на сервері перед відправкою FCM/APNs.
  • Видалення учасника без cleanup: після кика користувач технічно отримує WS-события якщо з'єднання не закрито. Потрібен примусовий disconnect через сигнал на WS-сервері.
  • Відсутність optimistic updates: повідомлення з'являється у UI лише після ответу сервера. Правильно — показати одразу зі статусом «sending», оновити/откатити при ответе.

Терміни та склад робіт

Базовий груповий чат (створення груп, ролі admin/member, повідомлення з пагінацією, пуші) — 3-4 тижні. Повна функціональність (медіа, упоминання, link preview, офлайн-синхронізація, квоти хранилища, галерея групи) — 2-3 місяці. Для Flutter-проекту — приблизно на 30% швидше за рахунок єдиного UI-шару.

Вартість рассчитується після детального ТЗ: склад платформ, обсяг груп (ліміт учасників), вимоги до шифрування та офлайн-режиму істотно впливають на архітектурні рішення.