Building a Full-Stack React App with Next.js & Firebase

Published at: December 10, 2022

Building full-stack applications used to require separate front-end and back-end technologies, complex server setups, and significant configuration. However, with modern tools like Next.js and Firebase, developers can build full-stack apps with ease, without the hassle of managing separate infrastructure. In this tutorial, we’ll go over how to build a full-stack React app using Next.js and Firebase, covering everything from authentication and Firestore integration to using serverless functions for backend logic.


Why Next.js & Firebase?

Next.js

Next.js is a popular React framework that simplifies building production-ready React applications. With built-in features like server-side rendering (SSR), static site generation (SSG), API routes, and automatic code splitting, Next.js streamlines the development process. It’s especially powerful when building full-stack apps since it allows both frontend and backend logic to coexist in one codebase.

Firebase

Firebase is a suite of cloud-based tools that offer scalable backend services, including authentication, databases (Firestore and Realtime Database), hosting, cloud functions, and more. Firebase’s ease of use, integration with JavaScript/React, and automatic scaling make it a great choice for building full-stack applications with minimal configuration.


Step 1: Setting Up Next.js

Let’s start by creating a Next.js project.

  1. Install Next.js:
    Open your terminal and run the following command to create a new Next.js project:
   npx create-next-app@latest my-fullstack-app
   cd my-fullstack-app
  1. Start the Development Server:
    Once the installation is complete, start the development server:
   npm run dev

Visit http://localhost:3000 in your browser to confirm that your Next.js app is working.


Step 2: Setting Up Firebase

  1. Create a Firebase Project:
  • Go to Firebase Console.
  • Click on “Add Project,” follow the steps, and create a new project.
  1. Enable Firebase Authentication:
  • In the Firebase console, navigate to Authentication in the left sidebar.
  • Under the Sign-in method tab, enable Email/Password authentication.
  • You can also enable other providers like Google or GitHub if needed.
  1. Enable Firestore and Realtime Database:
  • In the Firebase console, navigate to Firestore Database in the left sidebar.
  • Create a Firestore database by following the prompts.
  • If you want to use the Realtime Database as well, enable it under Realtime Database.
  1. Install Firebase SDK:
    In your Next.js project, install the Firebase SDK by running:
   npm install firebase
  1. Firebase Configuration:
    After setting up Firebase, go to your Firebase project settings and find your Firebase configuration object. It looks like this:
   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",
   };

Copy this object and save it for later use.


Step 3: Authentication with Firebase

Now let’s implement authentication using Firebase’s email/password authentication.

  1. Create Firebase Initialization File:
    In your Next.js project, create a file called firebase.js in the root directory. This file will initialize Firebase and export the necessary methods for authentication.
   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",
   };

   if (!firebase.apps.length) {
     firebase.initializeApp(firebaseConfig);
   }

   const auth = firebase.auth();
   const firestore = firebase.firestore();

   export { auth, firestore };
  1. Create Authentication Forms:
    Create a new file components/Auth.js where you’ll define your authentication form components (for login and signup).
   import { useState } from "react";
   import { auth } from "../firebase";

   const Auth = () => {
     const [email, setEmail] = useState("");
     const [password, setPassword] = useState("");
     const [error, setError] = useState(null);

     const handleLogin = async (e) => {
       e.preventDefault();
       try {
         await auth.signInWithEmailAndPassword(email, password);
       } catch (err) {
         setError(err.message);
       }
     };

     const handleSignup = async (e) => {
       e.preventDefault();
       try {
         await auth.createUserWithEmailAndPassword(email, password);
       } catch (err) {
         setError(err.message);
       }
     };

     return (
       <div>
         <h2>Login / Signup</h2>
         {error && <p>{error}</p>}
         <form>
           <input
             type="email"
             value={email}
             onChange={(e) => setEmail(e.target.value)}
             placeholder="Email"
           />
           <input
             type="password"
             value={password}
             onChange={(e) => setPassword(e.target.value)}
             placeholder="Password"
           />
           <button onClick={handleLogin}>Login</button>
           <button onClick={handleSignup}>Sign Up</button>
         </form>
       </div>
     );
   };

   export default Auth;
  1. Implement Authentication in Pages:
    Now, import the Auth component into your pages/index.js and render it for users who are not logged in.

Step 4: Firestore Integration

  1. Add Data to Firestore:
    Use Firestore to store user data once authenticated. Here’s an example of how you can save user information in Firestore after login.
   import { useEffect } from "react";
   import { auth, firestore } from "../firebase";

   const UserProfile = () => {
     useEffect(() => {
       const user = auth.currentUser;
       if (user) {
         firestore.collection("users").doc(user.uid).set({
           email: user.email,
           name: "John Doe",
         });
       }
     }, []);

     return <div>Profile Information</div>;
   };

   export default UserProfile;

Step 5: Using Serverless Functions for Backend Logic

Next.js provides a way to build API routes, which can act as your serverless functions. These API routes are great for handling backend logic like CRUD operations, authentication, and more.

  1. Create API Routes:
    In your pages/api folder, create a new file data.js for managing Firestore data.
   import { firestore } from "../../firebase";

   export default async function handler(req, res) {
     if (req.method === "POST") {
       const { data } = req.body;
       try {
         const docRef = await firestore.collection("data").add(data);
         res.status(200).json({ id: docRef.id });
       } catch (err) {
         res.status(500).json({ error: err.message });
       }
     }
   }
  1. Calling API Routes in the Frontend:
    In your React components, you can call these API routes like this:
   const addData = async (data) => {
     const response = await fetch("/api/data", {
       method: "POST",
       headers: {
         "Content-Type": "application/json",
       },
       body: JSON.stringify({ data }),
     });

     const result = await response.json();
     console.log(result);
   };

Step 6: Deploying the App

Once you’ve built your app, you can easily deploy it using Vercel (the platform behind Next.js) and Firebase Hosting.

  1. Deploy Next.js App on Vercel:
  • Push your code to GitHub.
  • Go to Vercel, sign in, and create a new project linked to your GitHub repository.
  • Vercel will automatically deploy your Next.js app and set up continuous deployment.
  1. Deploy Firebase App:
  • Use Firebase CLI to deploy Firestore and Authentication settings.
  • Run the following command to deploy your Firebase project:
   firebase deploy

Conclusion

By combining Next.js and Firebase, you can build a fully functional, full-stack React app with minimal setup. This powerful combination allows you to focus on creating great features and improving user experience while leveraging Firebase’s serverless backend.

With Firebase’s authentication, Firestore, real-time database, and serverless functions, along with Next.js’s seamless integration and API routes, building full-stack applications has never been easier.

Now you have everything you need to build and deploy your own full-stack React app

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 *