Group Chat in Mobile App

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Group Chat in Mobile App
Complex
from 1 week to 3 months
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Building Group Chat in Mobile Apps

Group chat is harder than private not by multiples but by orders of magnitude. Private chat has two participants — all events sync through one WebSocket to one conversation. Group chat with 200 participants requires the server to fanout each message to 199 connections, calculate unread correctly for each, not crush Redis under load, and work correctly when part of participants are offline. This is already an architecture problem, not just UI.

Server Architecture: Fanout and Presences

Message Distribution

Most painful part — delivering message to all group members. Synchronous fanout ("sent → pushed to all connections → responded to client") doesn't scale: with group of 500 people, iterating active connections takes tens of milliseconds, and if there are multiple WebSocket servers — participant connections spread across different nodes.

Correct scheme: client → WebSocket server → queue (Redis Pub/Sub or Kafka topic per group) → each WebSocket server reads from its queue and delivers to online participants → for offline participants — push notification queue.

For groups up to 100 members, Redis Pub/Sub with channel-per-group works well. For larger — Kafka or NATS JetStream with consumer groups.

Unread Message Counts

Classic mistake — store last_read_message_id in group_members table and on each request count SELECT COUNT(*) WHERE id > last_read_message_id. On group with thousands of messages and hundreds of members, this kills the database.

Working approach: Redis Hash unread:{user_id}:{group_id} → increment on each new message in group, reset when opening chat. Total badge — HVALS unread:{user_id} and sum on client. On Redis restart — recalculate from PostgreSQL as fallback.

Roles and Permissions

Schema: owner, admin, member. Permissions granularly: can_send_messages, can_add_members, can_remove_members, can_edit_group_info. Stored in group_members.role + JSON field permissions for custom overrides. Check at API middleware level before action execution.

Mobile UI: What's Technically Hard

Member List and Mentions

On @ input — popup with member filtering. On iOS: UITextView + custom UIView-overlay positioned above keyboard through KeyboardLayoutGuide. On selecting member — insert attributed string with NSAttributedString and custom NSTextAttachment or just colored range.

In Jetpack Compose: BasicTextField with custom VisualTransformation for mention coloring + Popup with LazyColumn for dropdown. @ trigger — through TextFieldValue.text.lastIndexOf('@') with 200ms debounce.

On backend when saving message — parse mentions with regex, create message_mentions[] records, separate push notification to mentioned members even if they muted group.

Media and Files in Group

Photos, videos, documents — upload through presigned S3 URL like in private chat, but with additional quota check (storage limit per group or per user). Group media gallery — separate screen with UICollectionView/LazyVerticalGrid, query from messages table by type IN ('image','video') AND group_id = ? with pagination.

Link preview: on server when receiving message with URL — async job (Sidekiq/Celery) parses Open Graph metadata, caches in Redis for 24h, client gets preview data in message.updated event.

Typing Indicator

WebSocket event typing.start / typing.stop from client → server broadcasts to group with user_id typing → clients show "Ivan is typing...". Problem: with 20 people typing simultaneously, UX breaks. Limitation: show max 3 names, then "and N more people are typing". Timeout: if typing.stop doesn't arrive — auto-hide after 5 seconds.

Offline and Sync

Group chat requires local database. SQLite through SQLCipher (encryption) — schema: groups, messages, group_members. On app startup — sync with server: request all groups with last_synced_at, then for each group — messages after last message_id. Conflicts on simultaneous edit — Last Write Wins by updated_at.

On iOS — GRDB.swift over SQLite, on Android — Room with Flow subscription for reactive UI updates.

Common Self-Implementation Mistakes

  • N+1 loading group list: separate query last_message for each group. Solution: JOIN with subquery or denormalized last_message_preview field.
  • Push on all messages ignoring mute: member muted group but gets push. Check group_members.notifications_muted on server before sending FCM/APNs.
  • Delete member without cleanup: after kick user still gets WebSocket events if connection not closed. Need forced disconnect through signal on WebSocket server.
  • No optimistic updates: message appears in UI only after server response. Right — show immediately with "sending" status, update/rollback on response.

Timeframe and Scope

Basic group chat (group creation, admin/member roles, messages with pagination, push) — 3-4 weeks. Full functionality (media, mentions, link preview, offline sync, storage quotas, gallery) — 2-3 months. For Flutter project — roughly 30% faster due to unified UI layer.

Cost calculated after detailed spec: platforms, group size (member limit), encryption and offline requirements significantly affect architectural decisions.