How to Build a Real-Time Chat App with React and Firebase

Published on 20.6.2020

Building a real-time chat app is a great way to learn how to integrate Firebase with React. Firebase offers powerful tools like authenticationreal-time databases, and hosting, making it an excellent choice for building scalable and efficient applications.

In this tutorial, we’ll walk through the process of building a simple real-time chat app using React and Firebase. We’ll cover:

  1. Firebase Authentication for user management.
  2. Firebase Firestore for real-time messaging.
  3. State management using React’s useContext or the Recoil library.
  4. Deploying the app with Firebase Hosting.

Let’s get started!


Step 1: Setting Up Firebase

Before you start building your chat app, you need to set up a Firebase project. Follow these steps:

  1. Go to the Firebase ConsoleFirebase Console
  2. Click on Create a project, and follow the prompts to create a new Firebase project.
  3. Once your project is created, you’ll be redirected to the project dashboard.

Enable Firebase Authentication

Firebase Authentication helps us manage users and allow them to sign in to our app. We’ll use Google Authentication for this example:

  1. In the Firebase Console, go to the Authentication section.
  2. Under the Sign-in method tab, enable Google as a sign-in provider.
  3. Save the changes.

Set Up Firestore Database

We’ll use Firestore, a real-time database, to store and fetch chat messages.

  1. In the Firebase Console, go to the Firestore Database section.
  2. Click on Create database and select Start in test mode (for development purposes).
  3. Click Enable to create the Firestore database.

Now, you’ll be able to store and retrieve chat messages in real time.


Step 2: Install Firebase and Create React App

Let’s create the React app and install Firebase.

  1. First, create a new React app if you don’t already have one:npx create-react-app react-chat-app cd react-chat-app
  2. Install Firebase by running:npm install firebase

Step 3: Initialize Firebase in Your App

Next, configure Firebase in your app.

  1. Create a new file in the src directory called firebase.js.
  2. Import Firebase and initialize it with your project’s configuration.import firebase from "firebase/app"; import "firebase/auth"; import "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", }; firebase.initializeApp(firebaseConfig); const auth = firebase.auth(); const db = firebase.firestore(); export { auth, db };

You can find the configuration values in your Firebase console under Project settings.


Step 4: Create the Authentication System

Let’s implement Google authentication so users can sign in.

  1. In App.js, import Firebase authentication and create the authentication logic.
import React, { useState, useEffect, useContext } from "react";
import { auth, db } from "./firebase";
import { useHistory } from "react-router-dom";

const AuthContext = React.createContext();

export const useAuth = () => useContext(AuthContext);

function App() {
  const [user, setUser] = useState(null);
  const history = useHistory();

  const signInWithGoogle = async () => {
    const provider = new firebase.auth.GoogleAuthProvider();
    await auth.signInWithPopup(provider);
  };

  const signOut = async () => {
    await auth.signOut();
  };

  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged(setUser);
    return unsubscribe;
  }, []);

  return (
    <AuthContext.Provider value={{ user, signInWithGoogle, signOut }}>
      <div className="App">
        {!user ? (
          <button onClick={signInWithGoogle}>Sign In with Google</button>
        ) : (
          <button onClick={signOut}>Sign Out</button>
        )}
        {user && <ChatApp />}
      </div>
    </AuthContext.Provider>
  );
}

export default App;

Here:

  • We created a context provider (AuthContext) to share authentication state across the app.
  • signInWithGoogle handles the sign-in process using Firebase’s GoogleAuthProvider.
  • signOut allows users to log out.

Step 5: Create the Chat Interface

Once users are signed in, we need to display the chat interface and allow them to send messages.

  1. Create a new component called ChatApp.js.
import React, { useState, useEffect } from "react";
import { db, auth } from "./firebase";

function ChatApp() {
  const [messages, setMessages] = useState([]);
  const [input, setInput] = useState("");

  useEffect(() => {
    // Get messages from Firestore in real time
    const unsubscribe = db.collection("messages")
      .orderBy("timestamp")
      .onSnapshot(snapshot => {
        setMessages(snapshot.docs.map(doc => doc.data()));
      });

    return () => unsubscribe();
  }, []);

  const sendMessage = async (e) => {
    e.preventDefault();
    if (input.trim()) {
      await db.collection("messages").add({
        text: input,
        uid: auth.currentUser.uid,
        name: auth.currentUser.displayName,
        timestamp: firebase.firestore.FieldValue.serverTimestamp(),
      });
      setInput("");
    }
  };

  return (
    <div className="chat-app">
      <div className="messages">
        {messages.map((message, index) => (
          <div key={index}>
            <strong>{message.name}</strong>: {message.text}
          </div>
        ))}
      </div>

      <form onSubmit={sendMessage}>
        <input
          type="text"
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="Type a message..."
        />
        <button type="submit">Send</button>
      </form>
    </div>
  );
}

export default ChatApp;

Here:

  • useEffect listens for real-time updates to the messages in Firestore.
  • sendMessage adds a new message to Firestore.
  • We display each message in the chat window.

Step 6: Manage State Efficiently with useContext or Recoil

If your app grows more complex, managing global state like the user’s authentication status or messages might become challenging. You can either use React’s useContext or Recoil for state management.

Option 1: Using useContext

We’ve already set up useContext for authentication in the AuthContext.

Option 2: Using Recoil for State Management

Install Recoil:

npm install recoil

Wrap your app in a RecoilRoot in index.js:

import { RecoilRoot } from "recoil";
import App from "./App";

ReactDOM.render(
  <RecoilRoot>
    <App />
  </RecoilRoot>,
  document.getElementById("root")
);

Then use atom and selector from Recoil to manage the chat messages and other states.


Step 7: Deploying the Chat App with Firebase Hosting

To deploy your chat app using Firebase Hosting:

  1. Install Firebase CLI:npm install -g firebase-tools
  2. Log in to Firebase using your Google account:firebase login
  3. Initialize Firebase Hosting:firebase init Select Hosting and follow the prompts to set up hosting for your app.
  4. Finally, deploy the app:firebase deploy

Your app will now be live on Firebase Hosting!


Conclusion

In this tutorial, we built a real-time chat app with React and Firebase. We covered:

  • Firebase authentication to handle user sign-in.
  • Firestore to store and retrieve messages in real time.
  • State management using React’s useContext or Recoil for more complex state management needs.
  • Deploying the app with Firebase Hosting.

This is a basic chat app, and you can extend it with features like image sharing, notifications, or even group chats.

Happy coding, and enjoy building with Firebase and React!

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *