Open In App

Chat Application using React Hooks and Firebase

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:

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.



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;




// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
// TODO: Add SDKs for Firebase products that you want to use
import { getAuth } from "firebase/auth";
import { getFirestore } from 'firebase/firestore'
 
 
// Your web app's Firebase configuration
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
};
 
// Initialize Firebase
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app)
export const db = getFirestore(app)




// App.js
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);
    //  console.log(user)
    return (
        <div className={style.appContainer}>
            <section className='{style.sectionContainer}'>
             
                <Navbar />
                {user ? <Chat /> : null}
            </section>
        </div>
    );
}
 
export default App;




// Chat.jsx
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>
            {/* Send Message Compoenent */}
            <SendMessage scroll={scroll} />
            <span ref={scroll}></span>
        </>
    );
};
 
export default Chat;




// Message.jsx
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;




// NavBar.jsx
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;




// SendMessage.jsx
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;




// Signin.jsx
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




// LogOut.jsx
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


Article Tags :