This document provides detailed documentation for all services available in the react-firebase-chat library.
The FirebaseService handles Firebase initialization and provides access to Firebase services.
Initializes Firebase with the provided configuration.
import { initializeFirebase } from 'react-firebase-chat';
const firebaseConfig = {
apiKey: "your-api-key",
authDomain: "your-project.firebaseapp.com",
projectId: "your-project-id",
storageBucket: "your-project.appspot.com",
messagingSenderId: "123456789",
appId: "your-app-id"
};
initializeFirebase(firebaseConfig);Returns the Firestore instance.
import { getFirebaseFirestore } from 'react-firebase-chat';
const db = getFirebaseFirestore();Returns the Firebase Auth instance.
import { getFirebaseAuth } from 'react-firebase-chat';
const auth = getFirebaseAuth();Returns the Firebase Storage instance.
import { getFirebaseStorage } from 'react-firebase-chat';
const storage = getFirebaseStorage();The ChatService handles all chat-related operations including conversations, messages, and real-time subscriptions.
Returns the singleton instance of ChatService.
import { ChatService } from 'react-firebase-chat';
const chatService = ChatService.getInstance();createConversation(memberIds: string[], initiatorId: string, type?: 'private' | 'group', name?: string, conversationId?: string, otherName?: string): Promise<string>
Creates a new conversation.
Parameters:
memberIds: string[]- Array of member user IDsinitiatorId: string- ID of the user creating the conversationtype?: 'private' | 'group'- Type of conversation (default: 'private')name?: string- Optional name for the conversationconversationId?: string- Optional specific conversation IDotherName?: string- Optional name for other participants
Returns: Promise<string> - The conversation ID
const conversationId = await chatService.createConversation(
['user1', 'user2'],
'initiatorId',
'private',
'My Chat'
);sendMessage(conversationId: string, message: Omit<IMessage, 'id' | 'createdAt' | 'user'>, conversationOptions?: object): Promise<void>
Sends a message to a conversation.
Parameters:
conversationId: string- The conversation IDmessage: Omit<IMessage, 'id' | 'createdAt' | 'user'>- Message dataconversationOptions?: object- Optional conversation creation options
await chatService.sendMessage(conversationId, {
text: 'Hello world!',
type: MediaType.text,
senderId: 'user123',
readBy: { user123: true },
path: '',
extension: ''
}, {
memberIds: ['user1', 'user2'],
name: 'Chat Name'
});subscribeToMessages(conversationId: string, callback: (messages: IMessage[], lastDoc?: DocumentSnapshot) => void, limitCount?: number): () => void
Subscribes to real-time message updates.
Parameters:
conversationId: string- The conversation IDcallback: (messages: IMessage[], lastDoc?: DocumentSnapshot) => void- Callback functionlimitCount?: number- Maximum number of messages to fetch (default: 50)
Returns: () => void - Unsubscribe function
const unsubscribe = chatService.subscribeToMessages(
conversationId,
(messages, lastDoc) => {
console.log('New messages:', messages);
// Handle pagination with lastDoc
},
50
);
// Later, unsubscribe
unsubscribe();subscribeToUserConversations(userId: string, callback: (userConversations: any[]) => void): () => void
Subscribes to user's conversation summaries.
const unsubscribe = chatService.subscribeToUserConversations(
'user123',
(userConversations) => {
console.log('User conversation summaries:', userConversations);
}
);Updates typing status for a user in a conversation.
await chatService.updateTypingStatus(conversationId, 'user123', true);subscribeToTypingStatus(conversationId: string, callback: (typingUsers: Record<string, boolean>) => void): Unsubscribe
Subscribes to typing status updates.
const unsubscribe = chatService.subscribeToTypingStatus(
conversationId,
(typingUsers) => {
console.log('Users typing:', typingUsers);
}
);Updates unread message count for a user.
await chatService.updateUnread(conversationId, 'user123', 5);Uploads a file to Firebase Storage.
const result = await chatService.uploadFile(file, conversationId);
console.log('File uploaded:', result.downloadURL);Deletes a message.
await chatService.deleteMessage(conversationId, 'message123');getMessagesWithPagination(conversationId: string, limitCount?: number, latestMessageDoc?: DocumentSnapshot): Promise<IMessage[]>
Gets messages with pagination support.
const messages = await chatService.getMessagesWithPagination(
conversationId,
50,
lastDocument
);The UserService handles user-related operations.
Returns the singleton instance of UserService.
import { UserService } from 'react-firebase-chat';
const userService = UserService.getInstance();Checks if a user document exists.
const exists = await userService.userExists('user123');createUserIfNotExists(userId: string, userData?: Partial<IUserInfo & Pick<UserProfileProps, 'status'>> & Record<string, unknown>): Promise<void>
Creates a user document if it doesn't exist.
await userService.createUserIfNotExists('user123', {
name: 'John Doe',
avatar: 'https://example.com/avatar.jpg',
status: UserStatus.online
});Gets all users from the users collection.
const users = await userService.getAllUsers();import { ChatService, UserService, initializeFirebase } from 'react-firebase-chat';
// Initialize Firebase
initializeFirebase(firebaseConfig);
// Get service instances
const chatService = ChatService.getInstance();
const userService = UserService.getInstance();
// Create users
await userService.createUserIfNotExists('user1', { name: 'Alice' });
await userService.createUserIfNotExists('user2', { name: 'Bob' });
// Create conversation
const conversationId = await chatService.createConversation(
['user1', 'user2'],
'user1',
'private'
);
// Send message
await chatService.sendMessage(conversationId, {
text: 'Hello Bob!',
type: MediaType.text,
senderId: 'user1',
readBy: { user1: true },
path: '',
extension: ''
});
// Subscribe to messages
const unsubscribe = chatService.subscribeToMessages(
conversationId,
(messages) => {
console.log('Messages:', messages);
}
);import { ChatService, IMessage, MediaType } from 'react-firebase-chat';
class ChatManager {
private chatService: ChatService;
constructor() {
this.chatService = ChatService.getInstance();
}
async sendMessageWithRetry(
conversationId: string,
text: string,
senderId: string,
maxRetries: number = 3
): Promise<void> {
let attempts = 0;
while (attempts < maxRetries) {
try {
await this.chatService.sendMessage(conversationId, {
text,
type: MediaType.text,
senderId,
readBy: { [senderId]: true },
path: '',
extension: ''
});
return; // Success
} catch (error) {
attempts++;
if (attempts >= maxRetries) {
throw new Error(`Failed to send message after ${maxRetries} attempts: ${error.message}`);
}
// Wait before retry
await new Promise(resolve => setTimeout(resolve, 1000 * attempts));
}
}
}
async createGroupChat(
memberIds: string[],
initiatorId: string,
groupName: string
): Promise<string> {
try {
// Ensure all users exist
await Promise.all(
memberIds.map(userId =>
this.chatService.userService.createUserIfNotExists(userId)
)
);
// Create group conversation
return await this.chatService.createConversation(
memberIds,
initiatorId,
'group',
groupName
);
} catch (error) {
throw new Error(`Failed to create group chat: ${error.message}`);
}
}
}import { ChatService, IMessage } from 'react-firebase-chat';
class MessageMonitor {
private chatService: ChatService;
private subscriptions: Map<string, () => void> = new Map();
constructor() {
this.chatService = ChatService.getInstance();
}
startMonitoring(conversationId: string): void {
const unsubscribe = this.chatService.subscribeToMessages(
conversationId,
(messages: IMessage[]) => {
this.handleNewMessages(messages);
}
);
this.subscriptions.set(conversationId, unsubscribe);
}
stopMonitoring(conversationId: string): void {
const unsubscribe = this.subscriptions.get(conversationId);
if (unsubscribe) {
unsubscribe();
this.subscriptions.delete(conversationId);
}
}
private handleNewMessages(messages: IMessage[]): void {
messages.forEach(message => {
console.log(`New message from ${message.senderId}: ${message.text}`);
// Custom logic here
if (message.text?.includes('@me')) {
this.handleMention(message);
}
});
}
private handleMention(message: IMessage): void {
console.log('You were mentioned in a message!');
// Show notification, update UI, etc.
}
cleanup(): void {
this.subscriptions.forEach(unsubscribe => unsubscribe());
this.subscriptions.clear();
}
}All service methods can throw errors. Here's how to handle them properly:
import { ChatService } from 'react-firebase-chat';
const chatService = ChatService.getInstance();
try {
await chatService.sendMessage(conversationId, messageData);
} catch (error) {
if (error.message.includes('permission-denied')) {
console.error('Permission denied: Check Firestore rules');
} else if (error.message.includes('not-found')) {
console.error('Conversation not found');
} else {
console.error('Unexpected error:', error.message);
}
}interface IMessage {
id: string;
text?: string;
createdAt: number;
image?: string;
video?: string;
audio?: string;
system?: boolean;
sent?: boolean;
received?: boolean;
pending?: boolean;
senderId?: string;
type?: MediaType;
readBy?: Record<string, boolean>;
}
interface IConversation {
id: string;
members: string[];
latestMessage?: IMessage;
latestMessageTime?: number;
unRead?: number;
title?: string;
type: 'private' | 'group';
createdAt: number;
updatedAt: number;
}
interface IUser {
id: string | number;
name?: string;
avatar?: string;
}
enum MediaType {
text = 'text',
image = 'image',
voice = 'voice',
video = 'video',
file = 'file',
system = 'system'
}interface FirebaseConfig {
apiKey: string;
authDomain: string;
projectId: string;
storageBucket: string;
messagingSenderId: string;
appId: string;
}
interface EncryptionFunctions {
generateKeyFunctionProp?: (key: string) => Promise<string>;
encryptFunctionProp?: (text: string) => Promise<string>;
decryptFunctionProp?: (text: string) => Promise<string>;
}- Always use try-catch blocks when calling service methods
- Unsubscribe from listeners to prevent memory leaks
- Check if Firebase is initialized before using services
- Handle offline scenarios gracefully
- Use pagination for large message lists
- Implement retry logic for critical operations
- Validate input data before sending to services
-
"Firebase not initialized" error
- Ensure
initializeFirebase()is called before using services - Check that Firebase config is valid
- Ensure
-
Permission denied errors
- Verify Firestore security rules
- Check user authentication status
-
Memory leaks from subscriptions
- Always call unsubscribe functions
- Clean up subscriptions in component unmount
-
Messages not appearing
- Check conversation ID is correct
- Verify user is a member of the conversation
- Check Firestore rules allow read access