Features
Typing Indicators
Typing indicators show when other users are currently typing in a room. This feature uses Firebase Realtime Database for fast, real-time updates with automatic cleanup.
How It Works
Data Structure
Typing status is stored in Realtime Database:
typing/{roomId}/{uid}: true | nullWhen a user is typing, their node is set to true. When they stop typing, the node is removed (set to null).
Sending Typing Status
When a user types in the chat input, handleTyping(roomId, uid) is called from typing.service.ts:
- Sets the typing node to
true(only once per typing session to minimize writes) - Sets up
onDisconnectto automatically remove the node if connection drops - Starts a timeout (default 3 seconds) that will clear typing status if no further typing occurs
- Each keystroke resets the timeout, so typing status stays active while the user is actively typing
This debouncing approach reduces database writes while still providing responsive typing indicators.
Clearing Typing Status
Typing status is cleared in two scenarios:
- Timeout: After
TYPING_TIMEOUT_MS(default 3000ms) of no typing activity,clearTyping(roomId, uid)is called automatically - Message sent: When the user sends a message, typing status is cleared immediately
- Connection drop: If the user's connection drops,
onDisconnectautomatically removes the typing node
Receiving Typing Status
Subscribing to Typing
To see who is typing in a room, use subscribeToTyping from typing.service.ts:
subscribeToTyping(roomId, (typingIds) => {
// typingIds is an array of UIDs currently typing
// e.g. ["uid1", "uid2"]
});The callback receives an array of user IDs who are currently typing. The subscription automatically updates whenever someone starts or stops typing.
Using the Hook
Components use useTypingIndicator hook to get typing status:
const typingIds = useTypingIndicator(roomId);
// typingIds is an array of UIDs currently typing
// Excludes the current user automatically
// Returns empty array if roomId is nullThe hook automatically filters out the current user (you don't want to see your own typing indicator) and handles subscription cleanup when the component unmounts or roomId changes.
UI Display
TypingIndicator Component
The template includes a TypingIndicator component that displays typing status:
- Shows animated dots when users are typing
- Displays user names (e.g., "John, Jane are typing...")
- Automatically hides when no one is typing
- Positioned at the bottom of the message list, above the input field
The component uses useTypingIndicator to get typing IDs and useUserInfo to fetch user names for display.
Performance Optimizations
The typing indicator system is optimized for performance:
- Debounced writes: Typing status is only written once per typing session, not on every keystroke
- Automatic cleanup: Timeout and onDisconnect ensure typing nodes don't persist unnecessarily
- Realtime Database: Fast updates with lower latency than Firestore for this ephemeral data
- Selective subscriptions: Only active rooms have typing subscriptions, reducing unnecessary listeners
Implementation Details
Key files for typing indicators:
features/chat/services/typing.service.ts– handleTyping, clearTyping, subscribeToTypingfeatures/chat/hooks/use-typing-indicator.ts– React hook for subscribing to typing statusfeatures/chat/components/ui/typing-indicator.tsx– UI component that displays typing statusfeatures/chat/components/room-pane/chat-input.tsx– Input component that calls handleTyping on user inputfeatures/chat/constants/chat.constants.ts– TYPING_TIMEOUT_MS constant (default: 3000ms)