The Multi-User Chat Application lets multiple people chat with each other in real-time. Using the latest web technologies, this app provides a smooth and responsive chat experience, making it easy to stay connected
- Introduction
- Features
- Tech Stack
- Installation
- Usage
- Project Structure
- API Endpoints
- Components
- Hooks
- Testing
- Logging and Monitoring
- Security
- Performance Optimization
- Deployment
- Code Quality
- Contribution Guidelines
- FAQ
- License
- Acknowledgements
The Multi-User Chat Application is a real-time messaging platform that enables seamless communication between multiple users. This application ensures a smooth, interactive, and responsive chat experience.
-
Real-Time Messaging: Instant communication between users.
-
User Authentication: Secure sign-up and sign-in.
-
User Presence: Show online/offline status of users.
-
Message History: Store and retrieve chat history.
-
Emoji Support: Add emojis to enhance user interactions.
-
Frontend: ReactJS
-
Backend: Firebase Functions
-
Database: Firebase Firestore
-
Authentication: Firebase Authentication
-
Storage: Firebase Storage
git clone https://github.com/s-satyajit/multi-user-chatApp.git
cd multi-user-chatApp
npm install
-
Create a Firebase project in the Firebase Console.
-
Obtain your Firebase configuration details from the project settings.
-
Create a
.env
file in the root directory and add your Firebase configuration.
REACT_APP_FIREBASE_API_KEY=<your-firebase-api-key>
REACT_APP_FIREBASE_AUTH_DOMAIN=<your-firebase-auth-domain>
REACT_APP_FIREBASE_PROJECT_ID=<your-firebase-project-id>
REACT_APP_FIREBASE_STORAGE_BUCKET=<your-firebase-storage-bucket>
REACT_APP_FIREBASE_MESSAGING_SENDER_ID=<your-firebase-messaging-sender-id>
REACT_APP_FIREBASE_APP_ID=<your-firebase-app-id>
Once the setup is complete, you can use the following features:
- Users can sign up and sign in using Firebase Authentication.
- Start new conversations and send messages in real-time using Firebase Firestore.
View the online/offline status of other users.
Here's an overview of the project's structure:
📦 Project Root
├── .gitignore # Git ignore rules
├── README.md # Project documentation
├── eslint.config.js # ESLint configuration
├── index.html # Main HTML file
├── package-lock.json # Lockfile for npm dependencies
├── package.json # Project metadata and dependencies
├── public/ # Public assets
│ ├── arrowDown.png # Arrow down icon
│ ├── arrowUp.png # Arrow up icon
│ ├── avatar.png # User avatar
│ ├── bg.jpg # Background image
│ ├── camera.png # Camera icon
│ ├── download.png # Download icon
│ ├── edit.png # Edit icon
│ ├── emoji.png # Emoji icon
│ ├── favicon.png # Favicon
│ ├── img.png # Generic image
│ ├── info.png # Info icon
│ ├── mic.png # Microphone icon
│ ├── minus.png # Minus icon
│ ├── more.png # More options icon
│ ├── phone.png # Phone icon
│ ├── plus.png # Plus icon
│ ├── search.png # Search icon
│ ├── theme.png # Theme icon
│ ├── video.png # Video icon
│ └── vite.svg # Vite logo
├── src/ # Source code
│ ├── App.jsx # Main React component
│ ├── assets/ # Asset files
│ │ └── react.svg # React logo
│ ├── components/ # React components
│ │ ├── chat/ # Chat feature components
│ │ │ ├── Chat.jsx # Chat component logic
│ │ │ └── chat.css # Chat component styles
│ │ ├── detail/ # Detail view components
│ │ │ ├── Detail.jsx # Detail component logic
│ │ │ └── detail.css # Detail component styles
│ │ ├── list/ # List view components
│ │ │ └── List.jsx # List component logic
│ │ ├── chatList/ # Chat list components
│ │ │ ├── ChatList.jsx # Chat list component logic
│ │ │ └── chatList.css # Chat list component styles
│ │ ├── addUser/ # Add user components
│ │ │ ├── addUser.jsx # Add user component logic
│ │ │ └── addUser.css # Add user component styles
│ │ ├── userInfo/ # User information components
│ │ │ ├── Userinfo.jsx # User information component logic
│ │ │ └── userInfo.css # User information component styles
│ │ ├── login/ # Login components
│ │ │ ├── Login.jsx # Login component logic
│ │ │ └── login.css # Login component styles
│ │ └── notification/ # Notification components
│ │ └── Notification.jsx # Notification component logic
│ ├── index.css # Global styles
│ ├── lib/ # Utility libraries
│ │ ├── UserStore.js # User state management
│ │ ├── chatStore.js # Chat state management
│ │ ├── firebase.js # Firebase configuration
│ │ └── upload.js # File upload utility
│ ├── main.jsx # Application entry
└───────vite.config.js # Vite configuration
Registers a new user.
Registers a new user using Firebase Authentication.
import { getAuth, createUserWithEmailAndPassword } from "firebase/auth";
const signUp = (email, password) => {
const auth = getAuth();
createUserWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
// Signed up successfully
})
.catch((error) => {
// Handle errors here
});
};
Authenticates a user using Firebase Authentication.
import { getAuth, signInWithEmailAndPassword } from "firebase/auth";
const signIn = (email, password) => {
const auth = getAuth();
signInWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
// Signed in successfully
})
.catch((error) => {
// Handle errors here
});
};
Fetches message history for a chat from Firebase Firestore.
import { getFirestore, collection, query, where, getDocs } from "firebase/firestore";
const getMessages = async (chatId) => {
const db = getFirestore();
const q = query(collection(db, "messages"), where("chatId", "==", chatId));
const querySnapshot = await getDocs(q);
const messages = [];
querySnapshot.forEach((doc) => {
messages.push(doc.data());
});
return messages;
};
Adds a new message to the chat in Firebase Firestore.
import { getFirestore, collection, addDoc } from "firebase/firestore";
const sendMessage = async (chatId, text, userId) => {
const db = getFirestore();
await addDoc(collection(db, "messages"), {
chatId,
text,
sender: userId,
timestamp: new Date()
});
};
Displays chat messages and a form to send new messages.
import React, { useState, useEffect } from 'react';
import useSocket from '../hooks/useSocket';
const ChatBox = ({ chatId }) => {
const [messages, setMessages] = useState([]);
const { socket, sendMessage } = useSocket(chatId);
useEffect(() => {
socket.on('message', (message) => {
setMessages((prevMessages) => [...prevMessages, message]);
});
return () => {
socket.off('message');
};
}, [socket]);
const handleSend = (e) => {
e.preventDefault();
const text = e.target.elements.message.value;
sendMessage({ chatId, text });
e.target.reset();
};
return (
<div className="chat-box">
{messages.map((msg, index) => (
<div key={index} className="message">{msg.text}</div>
))}
<form onSubmit={handleSend}>
<input type="text" name="message" placeholder="Type a message" required />
<button type="submit">Send</button>
</form>
</div>
);
};
export default ChatBox;
Custom hook for managing socket connections.
import { useState, useEffect } from 'react';
import io from 'socket.io-client';
const useSocket = (chatId) => {
const [socket, setSocket] = useState(null);
useEffect(() => {
const newSocket = io('http://localhost:5000', { query: { chatId } });
setSocket(newSocket);
return () => newSocket.close();
}, [chatId]);
const sendMessage = (message) => {
if (socket) {
socket.emit('send_message', message);
}
};
return { socket, sendMessage };
};
export default useSocket;
Custom hook for managing notifications.
import { useState, useEffect } from 'react';
const useNotifications = () => {
const [notifications, setNotifications] = useState([]);
useEffect(() => {
// Logic to fetch and subscribe to notifications
}, []);
const addNotification = (notification) => {
setNotifications((prevNotifications) => [...prevNotifications, notification]);
};
return { notifications, addNotification };
};
export default useNotifications;
To ensure the application functions correctly, run the following command to execute tests:
npm test
- Use Firebase Analytics for monitoring.
- Use Firebase Crashlytics for error tracking.
- Use HTTPS to encrypt data in transit.
- Store passwords securely using Firebase Authentication.
- Validate inputs to prevent XSS and other attacks.
- Regularly update dependencies.
- Use Firestore's offline capabilities.
- Implement lazy loading for components.
- Optimize Firestore queries.
- Use Firebase Performance Monitoring.
-
Build the project:
npm run build
-
Initialize Firebase in your project:
firebase init
-
Deploy the build directory:
firebase deploy
Set up CI/CD pipelines using GitHub Actions.
Example .github/workflows/deploy.yml
:
name: Deploy to Firebase
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Install dependencies
run: npm install
- name: Build project
run: npm run build
- name: Deploy to Firebase
run: firebase deploy --token ${{ secrets.FIREBASE_TOKEN }}
- Use linters like ESLint.
- Write unit and integration tests.
- Use tools like Prettier for code formatting.
- Conduct code reviews.
- Fork the repository.
- Clone your fork:
git clone https://github.com/your-username/multi-user-chatApp.git cd multi-user-chatApp
- Create a new branch:
git checkout -b feature-name
- Make your changes and commit:
git commit -m "Add feature-name"
- Push your branch:
git push origin feature-name
- Create a pull request.
Q: How do I report a bug?
A: Open an issue in the GitHub repository with a detailed description.
Q: Can I use this project for my own purposes?
A: Yes, this project is open-source and licensed under the MIT License.
This project is licensed under the MIT License.