A real-time Firebase chat monorepo providing ready-to-use UI components for both React Native and Web.
| Package | Description |
|---|---|
rn-firebase-chat |
React Native chat UI backed by @react-native-firebase |
@saigontechnology/react-firebase-chat |
Web chat UI backed by the Firebase JS SDK |
@saigontechnology/firebase-chat-shared |
Shared business logic (FirestoreServices, useChatScreen) |
@saigontechnology/chat-storage-providers |
Firebase Storage + Cloudinary adapters |
npm install rn-firebase-chat
# or
yarn add rn-firebase-chatnpm install \
@react-native-firebase/app \
@react-native-firebase/firestore \
react-native-gifted-chat \
react-native-keyboard-controller \
react-native-safe-area-context \
react-native-gesture-handler \
react-native-reanimated \
react-native-aes-cryptoOptional (file upload, camera, video):
npm install @react-native-firebase/storage react-native-image-picker react-native-vision-cameraIf you're using Expo, see the Expo Configuration Guide.
import { ChatProvider } from "rn-firebase-chat";
function App() {
return (
<ChatProvider
userInfo={{
id: "abc123",
name: "John Doe",
avatar: "https://example.com/avatar.jpg",
}}
>
<AppNavigation />
</ChatProvider>
);
}import { ListConversationScreen } from "rn-firebase-chat";
export const ListChatScreen = () => {
const handleItemPress = useCallback((data) => {
navigate("Chat", data);
}, []);
return <ListConversationScreen onPress={handleItemPress} />;
};import { ChatScreen as BaseChatScreen } from "rn-firebase-chat";
const partner = {
id: "xyz123",
name: "Tony",
avatar: "https://example.com/tony.jpg",
};
export const ChatScreen = () => (
<BaseChatScreen memberIds={[partner.id]} partners={[partner]} />
);npm install @saigontechnology/react-firebase-chat
# or
yarn add @saigontechnology/react-firebase-chatnpm install firebase react react-domOptional (animations, toasts, auto-sizing textarea):
npm install framer-motion react-hot-toast react-textarea-autosizeimport {
WebChatProvider,
ChatScreen,
} from "@saigontechnology/react-firebase-chat";
import "@saigontechnology/react-firebase-chat/styles.css";
import { initializeFirebase } from "@saigontechnology/react-firebase-chat";
initializeFirebase({ apiKey: "...", projectId: "..." /* ... */ });
function App() {
const currentUser = { id: "abc123", name: "John Doe" };
return (
<WebChatProvider currentUser={currentUser}>
<ChatScreen />
</WebChatProvider>
);
}See apps/web-vite/ for a working example.
- Mobile (iOS / Android): Getting Started — Mobile
- Web (Vite + React): Getting Started — Web
- Real-time messaging via Firestore
onSnapshot - Lazy conversation creation — Firestore document created on first send
- Typing indicators with configurable timeout
- Read receipts (
sent→received→seen) - Reply to messages with scroll-to-original
- Edit unseen messages
- Optional AES message encryption
- File / image / video upload (Firebase Storage or Cloudinary)
- Conversation name sync — each user writes their own display name into
names[userId] - Bad-word filtering via configurable word list
Deploy Firestore security rules and indexes from the monorepo root:
# Deploy both rules and indexes
firebase deploy --only firestore --project <your-project-id>
# Deploy rules only
firebase deploy --only firestore:rules --project <your-project-id>
# Deploy indexes only
firebase deploy --only firestore:indexes --project <your-project-id>The firebase.json at the repo root points to:
- Rules:
packages/rn-firebase-chat/firestore.rules - Indexes:
packages/rn-firebase-chat/firestore.indexes.json
Only rn-firebase-chat and @saigontechnology/react-firebase-chat are published. The shared and storage-providers packages are bundled inside via bundledDependencies.
# Build all packages first
pnpm build
# Publish React Native package
cd packages/rn-firebase-chat && pnpm publish
# Publish Web package
cd packages/react-firebase-chat && pnpm publish --access publicTo preview a tarball without publishing:
cd packages/rn-firebase-chat && pnpm pack
cd packages/react-firebase-chat && pnpm packSee the contributing guide.
MIT