Chat Application using React Hooks and Firebase
Last Updated :
07 Mar, 2024
In the era of technology messaging apps have become an aspect of our everyday routines enabling us to engage and interact with others promptly. For developers interested in crafting their messaging app leveraging React Hooks in conjunction, with Firebase presents a strategy, for constructing a dynamic, responsive, and expandable chat system. This piece will delve into the process of developing a messaging app using React Hooks and Firebase showcasing its features and advantages throughout.
Output Preview: Let us have a look at how the final output will look like.
Chat Room In logged in State
Prerequisites:
Approach to Create Chat Application:
- Authentication: Use Firebase Authentication for user sign-in and sign-out.
- Navbar: Create a Navbar component to display the app title and sign-in/sign-out buttons based on user authentication status.
- Chat Component: Implement a Chat component to display messages and allow users to send new messages using Firebase Firestore.
- Message Component: Develop a Message component to display individual messages with sender information.
- Styling: Apply styling to components for a visually appealing interface.
- Testing and Deployment: Test thoroughly and deploy your app to a hosting platform like Firebase Hosting.
- Message History: In the chat app past messages will be. Shown to users when they enter the chat room.
- Users have the ability to exchange messages instantly through real time messaging facilitating communication.
- Users can create an account. Access the chat app, by google sign in method for authentication.
Steps to Create Chat Application using React Hooks:
Step 1: Create a new project using below command
npx create-react-app chat-app
Step 2: While all the packages are installing lets create a project in Firebase.
- Head over to the Firebase dashboard
- Create a new project
- Once your project is set up you will have to configure a Firestore database and activate authentication for your project.
- Remember to save your Firebase setup information as it will be necessary on, in our React application.
Step 3: Install Required Dependencies Like Firebase & React Firebase Hooks using below command
npm install firebase react-firebase-hooks
Step 4: Install TailwindCSS
npm install -D tailwindcss
npx tailwindcss init
Step 5: Setup TailwindCSS Configuration By Adding Below Code to tailwind.config.js file in Content Section
"./src/**/*.{js,jsx,ts,tsx}"
Step 6: Import Below Code to index.css file
@tailwind base;
@tailwind components;
@tailwind utilities;
Folder Structure:
Project structure
The updated dependencies in package.json file will look like:
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
"firebase": "^9.9.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-firebase-hooks": "^5.0.3",
"react-google-button": "^0.7.2",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}
Step 7:Connect Your Firebase Project With Your App:
Now that we’ve got our project ready lets go ahead and link it to our Firebase project. Make a file called firebase.js and insert the code below making sure to swap out the setup specifics with your own;
Javascript
import { initializeApp } from "firebase/app" ;
import { getAuth } from "firebase/auth" ;
import { getFirestore } from 'firebase/firestore'
const firebaseConfig = {
apiKey: YOUR_API_KEY,
authDomain: YOUR_AUTH_DOMAIN,
projectId: YOUR_PROJECT_ID,
storageBucket: YOUR_STORAGE_BUCKET,
messagingSenderId: YOUR_MESSAGING_SENDER_ID,
appId: YOUR_APP_ID
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app)
export const db = getFirestore(app)
|
Javascript
import React from 'react' ;
import Navbar from './components/Navbar' ;
import Chat from './components/Chat' ;
import { auth } from './firebase' ;
import {
useAuthState
} from 'react-firebase-hooks/auth' ;
const style = {
appContainer: `max-w-[728px] mx-auto text-center`,
sectionContainer: `flex flex-col h-[90vh]
bg-gray-100 mt-10 shadow-xl border relative`,
};
function App() {
const [user] = useAuthState(auth);
return (
<div className={style.appContainer}>
<section className= '{style.sectionContainer}' >
<Navbar />
{user ? <Chat /> : null }
</section>
</div>
);
}
export default App;
|
Javascript
import React, {
useState,
useEffect,
useRef
} from 'react' ;
import Message from './Message' ;
import SendMessage from './SendMessage' ;
import { db } from '../firebase' ;
import {
query,
collection,
orderBy,
onSnapshot
} from 'firebase/firestore' ;
const style = {
main: `flex flex-col p-[10px]`,
};
const Chat = () => {
const [messages, setMessages] = useState([]);
const scroll = useRef();
useEffect(() => {
const q = query(collection(db, 'messages' ),
orderBy( 'timestamp' ));
const unsubscribe = onSnapshot(q, (querySnapshot) => {
let messages = [];
querySnapshot.forEach((doc) => {
messages.push({ ...doc.data(), id: doc.id });
});
setMessages(messages);
});
return () => unsubscribe();
}, []);
return (
<>
<main className={style.main}>
{messages &&
messages.map((message) => (
<Message key={message.id}
message={message} />
))}
</main>
{ }
<SendMessage scroll={scroll} />
<span ref={scroll}></span>
</>
);
};
export default Chat;
|
Javascript
import React from 'react' ;
import { auth } from '../firebase'
const style = {
message: `flex items-center shadow-xl m-4
py-2 px-3 rounded-tl-full rounded-tr-full`,
name: `absolute mt-[-4rem]
text-gray-600 text-xs`,
sent: `bg-[ #395dff] text-white flex-row-reverse
text-end float-right rounded-bl-full`,
received: `bg-[ #e5e5ea] text-black
float-left rounded-br-full`,
};
const Message = ({ message }) => {
const messageClass =
message.uid === auth.currentUser.uid
? `${style.sent}`
: `${style.received}`
return (
<div>
<div className={`${style.message}
${messageClass}`}>
<p className={style.name}>
{message.name}
</p>
<p>{message.text}</p>
</div>
</div>
);
};
export default Message;
|
Javascript
import React from 'react' ;
import SignIn from './SignIn'
import LogOut from './LogOut'
import { auth } from '../firebase'
import {
useAuthState
} from 'react-firebase-hooks/auth'
const style = {
nav: `bg-green-600 h-20 flex justify-between
items-center p-4`,
heading: `text-white text-3xl
flex justify-between items-center p-4`
}
const Navbar = () => {
const [user] = useAuthState(auth)
console.log(user)
return (
<div className={style.nav}>
<h1 className={style.heading}>
Geeks Chat App
</h1>
{user ? <LogOut /> : <SignIn />}
</div>
);
};
export default Navbar;
|
Javascript
import React, { useState } from 'react' ;
import {
auth,
db
} from '../firebase'
import {
addDoc,
collection,
serverTimestamp
} from 'firebase/firestore'
const style = {
form: `h-14 w-full max-w-[728px] flex text-xl absolute bottom-0`,
input: `w-full text-xl p-3 bg-white-900 text-black outline-none border-none`,
button: `w-[20%] bg-green-500`,
};
const SendMessage = ({ scroll }) => {
const [input, setInput] = useState( '' );
const sendMessage = async (e) => {
e.preventDefault()
if (input === '' ) {
alert( 'Please enter a valid message' )
return
}
const { uid, displayName } = auth.currentUser
await addDoc(collection(db, 'messages' ), {
text: input,
name: displayName,
uid,
timestamp: serverTimestamp()
})
setInput( '' )
scroll.current.scrollIntoView({ behavior: 'smooth' })
}
return (
<form onSubmit={sendMessage} className={style.form}>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
className={style.input}
type= 'text'
placeholder= 'Message'
/>
<button className={style.button} type= 'submit' >
Send
</button>
</form>
);
};
export default SendMessage;
|
Javascript
import React from 'react'
import GoogleButton from 'react-google-button'
import { auth } from '../firebase'
import {
GoogleAuthProvider,
signInWithRedirect
} from 'firebase/auth'
const style = {
wrapper: `flex justify-center`
}
const googleSignIn = () => {
const provider = new GoogleAuthProvider()
signInWithRedirect(auth, provider)
}
const SignIn = () => {
return (
<div className={style.wrapper}>
<GoogleButton onClick={googleSignIn} />
</div>
)
}
export default SignIn
|
Javascript
import React from 'react'
import { auth } from '../firebase'
const style = {
button: `bg-gray-200 px-4 py-2 hover:bg-gray-100`
}
const LogOut = () => {
const signOut = () => {
signOut(auth)
}
return (
<button onClick={() => auth.signOut()}
className={style.button}>
Logout
</button>
)
}
export default LogOut
|
To start the app run the following command.
npm start
Output:
Output
Share your thoughts in the comments
Please Login to comment...