Firebase Authentication with Next
Tags: firebase, authentication, nextjs, vercel
Published: 2021-11-12 18:15:22

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](https://www.youtube.com/watch?v=awd_oYcmrRA&t=528s) 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**

```javascript 
// .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**
```javascript
//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**

```javascript
// 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.

``` javascript
// 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](https://www.vercel.com), 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!!!