Firebase Authentication with Next
Chinwendu Agbaetuo
Posted on November 12, 2021
I had to work on a project that required me to setup Firebase authentication. This is my first time using Firebase, after countless research and numerous YouTube tutorials. I finally got a hang of it, so I would love to share how I was able to configure it as well as setup protected routes.
Step One: Setup Firebase Console
To setup the console this tutorial was helpful.
Step Two: Install Firebase packages
yarn add firebase
yarn add react-firebase-hooks
Step Three: Create .env.local file and add setup Firebase configuration
// .env.local
NEXT_PUBLIC_FIREBASE_API_KEY=<YOUR API KEY>
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=<YOUR AUTH DOMAIN>
NEXT_PUBLIC_FIREBASE_PROJECT_ID=<YOUR PROJECT ID>
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=<YOUR STORAGE BUCKET>
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=<YOUR SENDER ID>
NEXT_PUBLIC_FIREBASE_APP_ID=<YOUR APP ID>
NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=<YOUR MEASUREMENT ID>
Step Four: Setup Firebase configuration file
//firebaseClient.tsx
import { getAuth, GoogleAuthProvider } from "@firebase/auth";
import { initializeApp } from "firebase/app";
// Nextjs Web Firebase configuration
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,
measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
};
const firebaseApp = initializeApp(firebaseConfig);
export const googleProvider = new GoogleAuthProvider();
export const firebaseAuth = getAuth(firebaseApp);
Step Five: Pass firebase auth state where it is needed
// google-login.tsx
import { useAuthState } from "react-firebase-hooks/auth";
import { firebaseAuth, googleProvider } from "config/firebaseClient";
import { signInWithPopup } from "firebase/auth";
import Link from "next/link";
export default function GoogleSignIn () {
const handleLogin = async () => {
await signInWithPopup(firebaseAuth, googleProvider);
};
const [user, loading] = useAuthState(firebaseAuth);
return (
{loading ? (
<></>
) : (
<>
{user ? (
<img
src={user?.photoURL}
alt={user?.displayName} />
) : (
<button onClick={handleLogin}>
Login
</button>
)}
</>
)}
)
}
Step Six: Protected routes
Protecting routes that can only be accessed when user is authenticated.
// profile.tsx
import { useAuthState } from "react-firebase-hooks/auth";
import { firebaseAuth } from "config/firebaseClient";
import { signOut } from "firebase/auth";
import Link from "next/link";
export default function Profile() {
const [user] = useAuthState(firebaseAuth);
return <h1>This is the profile page</h1>
}
// Navigate to login page if user isn't authenticated
Profile.getInitialProps async function(ctx: any) {
const { req } = ctx;
const user = await firebaseAuth.currentUser;
if (!user) {
ctx.res.writeHead(302, {
Location: "/login",
});
ctx.res.end();
}
return { user };
};
Step Seven: Pass Environment variables into hosting platform
The .env.local
file is included in the .gitignore
file, that means it needs to be configured on the hosting platform. If hosting with vercel, go to the project settings
, and proceed to the Environment Variables
section, and fill in the Firebase configuration.
Please, let me know, if this method worked for you, or what can be improved. Thanks for reading!!!
Posted on November 12, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.