Back

NextJS 13 | Authenticate Users with Firebase

The Code

I committed all the code to this Github Repo.

Firebase Setup

import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';

const firebaseConfig = {
  apiKey: process.env.NEXT_PUBLIC_API_KEY,
  authDomain: process.env.NEXT_PUBLIC_AUTH_DOMAIN,
  projectId: process.env.NEXT_PUBLIC_PROJECT_ID,
  storageBucket: process.env.NEXT_PUBLIC_STORAGE_BUCKET,
  messagingSenderId: process.env.NEXT_PUBLIC_MESSAGING_SENDER_ID,
  appId: process.env.NEXT_PUBLIC_APP_ID,
};

const app = initializeApp(firebaseConfig);
const auth = getAuth(app);

export { app, auth };

Adding the Firebase Wrapper

In your root layout.tsx file:

import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import ClientWrapper from './components/ClientWrapper';
import './globals.css';

const inter = Inter({ subsets: ['latin'] });

export const metadata: Metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
};

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <ClientWrapper>{children}</ClientWrapper>
      </body>
    </html>
  );
}

Where the Client Wrapper has the firebase hooks to check if a user logs in or out:

'use client';

import { auth } from '@/firebase/config';
import { onAuthStateChanged } from 'firebase/auth';
import { useEffect } from 'react';

type Props = {
  children: React.ReactNode;
};

const ClientWrapper: React.FC<Props> = ({ children }) => {
  useEffect(() => {
    onAuthStateChanged(auth, (user) => {
      if (user) {
        const uid = user;
        console.log(uid);
      } else {
        console.log('No user');
      }
    });
  }, []);

  return <div>{children}</div>;
};

export default ClientWrapper;

Sign In Logic

This is where the actual logging in is called, when the user clicks the buttons.

'use client';

import { auth } from '@/firebase/config';
import { GoogleAuthProvider, signInWithRedirect, signOut } from 'firebase/auth';

export default function Home() {
  const onLogin = async () => {
    const provider = new GoogleAuthProvider();

    try {
      const res = await signInWithRedirect(auth, provider);
      console.log('res from function: ', res);
    } catch (err) {
      console.log('err: ', err);
    }
  };

  const onLogout = () => {
    signOut(auth);
  };

  return (
    <main className="flex min-h-screen flex-col items-center justify-center">
      <div className="flex justify-center items-center gap-4">
        <button className="p-2 px-4 rounded-md bg-rose-400" onClick={onLogout}>
          Log Out
        </button>
        <button className="p-2 px-4 rounded-md bg-indigo-400" onClick={onLogin}>
          Log In
        </button>
      </div>
    </main>
  );
}