logo studio roma
EN / ES

Back to Blog

Authentication with Firebase

Pablo Romera foto

Pablo Romera 

/

 February 19, 2024 / 6 min read

Pablo Romera foto

Easy Authentication with Firebase

Discover how authentication with Firebase can revolutionize your web design and development process, ensuring a seamless, secure, and user-friendly login experience.

Whether you're a seasoned developer or new to the scene, this guide will walk you through the essentials of Easy Authentication with Firebase, showcasing its benefits for business web design and development.


General Info

At its core, Firebase Authentication provides a highly secure, easy-to-use, and versatile authentication system. It supports authentication using passwords, phone numbers, popular federated identity providers like Google, Facebook, and Twitter, and more. This flexibility allows developers to tailor the authentication experience to their user's needs, making it a perfect fit for business web designs and development projects.

How Does Firebase Authentication Work?

Firebase Authentication works by managing user data securely on the backend while providing customizable front-end components for various authentication methods. When a user signs in, Firebase Authentication verifies their credentials and returns a token, which can then be used to access other services or custom backend logic securely.

Databases

Firebase offers two cloud-based, client-accessible document databases.

  • Cloud Firestore is the recommended enterprise-grade JSON-compatible document database, trusted by more than 250,000 developers. It's suitable for applications with rich data models requiring queryability, scalability, and high availability. It also offers low latency client synchronization and offline data access.
  • Realtime Database is the classic Firebase JSON database. It's suitable for applications with simple data models requiring simple lookups and low-latency synchronization with limited scalability.

We’ll use Cloud Firestore, but if you want to read more about advantages and disadvantages you can read the documentation: https://firebase.google.com/docs/database/rtdb-vs-firestore?hl=en

First Steps: Setting Up Firebase

  • Go to https://console.firebase.google.com
  • Sign in or sign-up to Firebase
  • Click Get Started and then Add project and set up a new project.
  • Disable the Google Analytics functionality on the next page if aren’t necessary.
  • Click the </> icon button to build the sign-in system for a web app and add a name for it.
  • Click the Register app button.
  • Add the Authentication product to your web app.
  • Add and enable your google access method.

Next steps: Cloud Firestore Initialization

Important things first. Install Firebase in your project:

npm install firebase

After that, create a folder called firebase with a firebaseConfig.js file in it to initialize our instance of Cloud Firestore.

components/firebase/firebaseConfig.js

import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
		...
};

const app = initializeApp(firebaseConfig);

const db = getFirestore(app);
export { db };

We could check if any other app was already initialized:

import { initializeApp, getApps } from "firebase/app";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
		...
};

const app = !getApps().length ? initializeApp(firebaseConfig) : getApps()[0];

const db = getFirestore(app);
export { db };

After creating our project on the Firebase web platform, we can configure the SDK and obtain the Firebase configuration information. Save this information in an .env file and then pass it to our firebaseConfig.js file. In the case of a Next.js project, we use NEXTPUBLIC, but depending on the technology stack employed, you might need to use REACTAPP or VITE_.

import { initializeApp, getApps } from "firebase/app";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
  apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
  authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
  storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
};

const app = !getApps().length ? initializeApp(firebaseConfig) : getApps()[0];

const db = getFirestore(app);
export { db };

Last steps: Firebase Authentication

Since we want to login to our web application, it's time to get started with Firebase Authentication.

components/firebase/firebaseConfig.js

import { initializeApp, getApps } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
		...
};

const app = !getApps().length ? initializeApp(firebaseConfig) : getApps()[0];

const db = getFirestore(app);
// Initialize Firebase Authentication and get a reference to the service
const auth = getAuth(app);
export { auth, db };

Set up the authentication context to read and subscribe to authentication data from your component.

import { createContext, useState, useEffect, useContext } from "react";
import {
  signInWithPopup,
  GoogleAuthProvider,
  signOut,
  onAuthStateChanged,
} from "firebase/auth";
import { auth } from "@/firebase/firebaseConfig";

export const AuthContext = createContext();

export const AuthContextProvider = ({ children }) => {
  const [user, setUser] = useState(null);

  const handleLogin = async () => {
    const provider = new GoogleAuthProvider();
    try {
      const result = await signInWithPopup(auth, provider);
      setUser(result.user);
    } catch (error) {
      const errorCredential = GoogleAuthProvider.credentialFromError(error);
      console.log("errorCredential: ", errorCredential);
      // ...
    }
  };

  const handleLogout = () => {
    signOut(auth);
    setUser(null);
  };

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

  return (
    <AuthContext.Provider value={{ handleLogin, handleLogout, user }}>
      {children}
    </AuthContext.Provider>
  );
};

export const UserAuth = () => {
  return useContext(AuthContext);
};

Add the login and logout buttons:

import React, { useContext, useEffect } from "react";
import Link from "next/link";

import { AuthContext } from "@/components/context/AuthContext";

import styles from "@/styles/Header.module.scss";

const Header = () => {
  const { handleLogin, handleLogout, user } = useContext(AuthContext);

  const handleAuth = () => {
    handleLogin();
  };

  const cancelAuth = () => {
    handleLogout();
  };

  return (
    <>
      <div className={styles.header}>
        <div className={styles.header__auth}>
          {!user && (
            <button
              onClick={handleAuth}
              className={styles["header__auth-loginBttn"]}
            >
              Log in
            </button>
          )}
          {user && (
            <Link
              href="/"
              onClick={cancelAuth}
              className={styles["header__auth-logoutBttn"]}
            >
              Log out
            </Link>
          )}
        </div>
      </div>
    </>
  );
};

export default Header;

Conclusion

Firebase Authentication offers a robust and flexible solution for managing authentication in web applications. With its wide range of authentication methods and ease of integration into existing projects, Firebase stands out as an invaluable tool for developers looking to implement a secure and customized authentication system. Additionally, the integration of Cloud Firestore for real-time data management extends the capabilities of applications, allowing for richer and more reactive user experiences. By following the steps provided in this guide, you will be well on your way to leveraging the full functionalities that Firebase has to offer, thereby enhancing security and user experience in your web projects.