Published: 1 July 2023
Introduction
Building a real-time chat app can be an exciting project to dive into, and using Next.js and Firebase is one of the most powerful combinations for quickly building such applications. Firebase offers real-time databases (like Firestore) and authentication features that integrate seamlessly with Next.js, making it an excellent choice for fast, scalable, and highly interactive apps.
In this tutorial, we’ll walk through the process of building a simple real-time chat application with Next.js and Firebase, leveraging Firebase for user authentication, real-time message updates with Firestore, and implementing basic message storage.
Why Choose Next.js & Firebase for a Real-Time Chat App?
- Next.js: A powerful React framework for building fast, server-rendered apps with ease. It comes with features like API routes, SSR, SSG, and ISR, which make it an excellent choice for building web applications that need scalability and performance.
- Firebase: Firebase provides easy-to-use services like Firestore, which is a NoSQL database that supports real-time data syncing across clients. It also offers authentication out of the box, making it ideal for quickly handling user login and security in your chat app.
Step-by-Step Guide to Building a Real-Time Chat App
Let’s dive into the steps to build our real-time chat application. In this app, we’ll focus on:
- Setting up Firebase for authentication and real-time messaging.
- Building the Next.js app to handle the frontend logic and real-time updates.
Step 1: Set Up Firebase Project
To get started, we’ll need to create a Firebase project.
- Go to Firebase Console: Head to Firebase Console and create a new project.
- Enable Firestore: In the Firebase console, go to Firestore Database and create a new Firestore database.
- Enable Firebase Authentication: Set up Firebase Authentication by going to the Authentication tab in the Firebase Console and enabling your preferred authentication method (e.g., Google, Email/Password).
- Install Firebase SDK: In your Next.js project, install the Firebase SDK.
npm install firebase
Step 2: Initialize Firebase in Your Project
Create a file for Firebase configuration and initialization. Typically, this file will contain the Firebase project details and initialize Firestore and Authentication.
Create a firebase.js
file in the lib
folder of your Next.js project.
// lib/firebase.js
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',
};
// Initialize Firebase
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
} else {
firebase.app();
}
const auth = firebase.auth();
const firestore = firebase.firestore();
export { auth, firestore };
Step 3: Implement Firebase Authentication
Next, we need to allow users to sign in. Firebase provides various authentication methods, such as email/password and third-party authentication like Google. Here, we’ll use Google authentication as an example.
Create a Login component for the user to log in using Google.
// components/Login.js
import { auth } from '../lib/firebase';
const Login = () => {
const handleLogin = async () => {
const provider = new firebase.auth.GoogleAuthProvider();
await auth.signInWithPopup(provider);
};
return (
<div>
<button onClick={handleLogin}>Log in with Google</button>
</div>
);
};
export default Login;
This will allow users to log in to the chat app with their Google account. Once authenticated, we will show them the chat interface.
Step 4: Build the Chat Interface
Create the Chat component that will allow authenticated users to send and receive messages in real-time.
// components/Chat.js
import { useState, useEffect } from 'react';
import { auth, firestore } from '../lib/firebase';
const Chat = () => {
const [message, setMessage] = useState('');
const [messages, setMessages] = useState([]);
const [user, setUser] = useState(null);
// Handle user authentication state
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(setUser);
return () => unsubscribe();
}, []);
// Fetch messages in real-time
useEffect(() => {
const unsubscribe = firestore
.collection('messages')
.orderBy('timestamp')
.onSnapshot(snapshot => {
setMessages(snapshot.docs.map(doc => doc.data()));
});
return () => unsubscribe();
}, []);
// Send a message to Firestore
const sendMessage = async (e) => {
e.preventDefault();
if (message.trim()) {
await firestore.collection('messages').add({
text: message,
uid: user.uid,
displayName: user.displayName,
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
});
setMessage('');
}
};
if (!user) return <Login />; // Show login if user is not authenticated
return (
<div>
<div className="messages">
{messages.map((msg, index) => (
<div key={index}>
<strong>{msg.displayName}</strong>: {msg.text}
</div>
))}
</div>
<form onSubmit={sendMessage}>
<input
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Type a message"
/>
<button type="submit">Send</button>
</form>
</div>
);
};
export default Chat;
Explanation:
- Authentication State: The component listens for changes in the authentication state using
onAuthStateChanged
. If the user is not logged in, the login page is displayed. - Real-Time Messaging: We use Firestore’s real-time feature with
onSnapshot()
to listen for new messages. Whenever a message is added to Firestore, the component automatically updates the UI. - Sending Messages: When the user sends a message, it’s added to Firestore with their
uid
,displayName
, and the message text. We also use Firestore’s server timestamp to order the messages.
Step 5: Displaying the Chat in a Next.js Page
Now, we need to display the Chat
component in a page. Create a new page, for example pages/chat.js
.
// pages/chat.js
import Chat from '../components/Chat';
const ChatPage = () => {
return (
<div>
<h1>Chat</h1>
<Chat />
</div>
);
};
export default ChatPage;
Step 6: Deploying to Vercel
After completing the app, you can deploy it to Vercel, the platform that integrates perfectly with Next.js.
- Push your project to a GitHub or GitLab repository.
- Go to Vercel and link your Git repository.
- Vercel will automatically deploy the app, and you’ll be able to access it with a unique URL.
Conclusion
In this guide, we’ve walked through building a real-time chat application with Next.js and Firebase. By integrating Firebase Authentication for user login and Firestore for real-time messaging, we’ve created a simple but powerful chat app that can scale as needed.
The combination of Next.js and Firebase allows for a fast, efficient, and easy-to-develop chat app, and by leveraging Firestore’s real-time updates, we can ensure smooth and seamless user interactions.
Feel free to extend this app by adding more features such as:
- User profile management
- Private messaging
- Message persistence across devices
The possibilities are endless!