Chat Module
Quick Answer
The chat module lives in src/core/chat. It provides conversation lists, one-to-one chat, group chat, messages, reactions, media messages, typing state, and backend hooks.
For Firebase-backed apps, chat uses a mix of Firestore listeners and Firebase callable Functions. That means local UI can render without a custom server, but production chat still needs Firebase Functions deployed and Firestore rules configured.
Source Map
src/core/chat
├── IMChat
├── IMChatScreen
├── IMConversationList
├── IMConversationListView
├── IMConversationView
├── api
├── assets
├── config.ts
└── index.ts
Important exports:
| Export | Purpose |
|---|---|
IMChatScreen | Full chat room screen for one-to-one and group conversations. |
IMConversationListView | Conversation list UI for the current user. |
IMConversationIconView | Avatar/group icon display for conversations. |
IMCreateGroupScreen | Group chat creation flow when the group chat flag is enabled. |
useChatChannels | Hook for the user's conversation list. |
useChatMessages | Hook for messages in one channel. |
useChatSingleChannel | Hook for a single channel document. |
useChatChannelsAndFriends | Combined chat and friend data when social graph is enabled. |
Backend Providers
The active chat backend is selected in:
src/core/chat/api/index.ts
Current provider options may include:
| Provider | Path | Use case |
|---|---|---|
| Firebase | src/core/chat/api/firebase | Default production path for Firebase apps. |
| AWS | src/core/chat/api/aws | AWS-backed app variants. |
| Backend | src/core/chat/api/backend | Custom server implementation. |
| Local | src/core/chat/api/local | Demo/local data implementation. |
Do not mix providers inside one app unless you intentionally migrate the full chat data layer.
Open A Chat Screen
Use the channel object expected by the app navigation flow. A one-to-one channel usually uses a deterministic ID made from the two user IDs.
const firstUserID = currentUser.id
const secondUserID = otherUser.id
const channelID =
firstUserID < secondUserID
? firstUserID + secondUserID
: secondUserID + firstUserID
navigation.navigate('ChatScreen', {
channel: {
id: channelID,
channelID,
participants: [currentUser, otherUser],
},
})
Prefer using the existing app screens and managers to create channels. They already handle group metadata, participant shape, and backend calls.
Firebase Requirements
For Firebase chat, verify:
- Firebase Auth is enabled.
- Firestore is enabled.
- Firebase Functions are deployed for channel and message operations.
- Firestore rules restrict channel/message reads to participants.
- Composite indexes exist for the queries used by conversation and message lists.
- Push notifications are configured if the app sends message notifications.
- Storage or media upload Functions are configured if chat supports media messages.
The Firebase chat client intentionally returns empty arrays on listener errors to avoid infinite loading. If a conversation list is blank, check logs and Firebase rules before changing UI state.
Media Messages
Media messages usually flow through:
src/core/camera
src/core/media
src/core/chat
A chat screen should handle these failure states separately:
- permission denied;
- image/video picker canceled;
- upload failed;
- message insert failed after upload;
- channel listener permission denied.
Switching To A Custom Backend
To replace Firebase chat with your own backend:
- Keep the UI exports from
src/core/chat. - Implement the same hook contracts in
src/core/chat/api/backend. - Switch exports in
src/core/chat/api/index.ts. - Make sure the new backend supports list channels, subscribe/fetch messages, create channel, send message, reactions, group updates, and delete/leave behavior.
- Re-test one-to-one chat, group chat, media messages, and blocked-user filtering.
Verification Checklist
Test:
- empty conversation list resolves without infinite loading;
- existing conversations load;
- one-to-one chat opens;
- group chat opens if enabled;
- text message sends;
- media message sends if enabled;
- message list updates in real time;
- unread/read state updates;
- blocked users are filtered;
- Firebase permission errors are visible in logs and do not leave a permanent spinner.
Troubleshooting
| Problem | Fix |
|---|---|
| Conversation screen loads forever | Confirm listener errors call the empty-state callback, then check Firestore rules and current user ID. |
| Messages do not send | Deploy Firebase Functions and check callable Function region/config. |
| User can read another user's chat | Tighten Firestore rules and validate channel participants. |
| Media messages fail | Check src/core/media, Firebase Storage/Functions, and Blaze plan requirements for uploads. |
| Group chat crashes | Confirm social graph/friends data is present and the group chat flag did not remove required screens. |