DEV Community

Thinh Nguyen
Thinh Nguyen

Posted on

How to Initialize a Firebase app in the new modular Web SDK in Next.js

Previously in Version 8

Most devs migrating to the new modular approach for delivering the firebase API typically have this code snippet that initializes their firebase app.

We'll start off by exporting the most basic service, being firebase/auth.

//initFirebase.ts
require("firebase/auth");

import firebase from "firebase/app";

const config = {
  // ...various env variables
};

export default function initializeFirebase() { 
  if (firebase.apps.length === 0) {
    return firebase.initializeApp(config);
  }
}

export const firebaseAuth = firebase.auth;
Enter fullscreen mode Exit fullscreen mode

Now in V9

In the latest version, we can re-factor the snippet into something like this:

// initFirebase.ts

import { FirebaseOptions, getApp, initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";

const config: FirebaseOptions = {
  // ...various env variables
};

function createFirebaseApp(config: FirebaseOptions) {
  try {
    return getApp();
  } catch {
    return initializeApp(config);
  }
}

const firebaseApp = createFirebaseApp(firebaseConfig);
export const firebaseAuth = getAuth(firebaseApp);
Enter fullscreen mode Exit fullscreen mode

Bonus: Initialize the latest Admin SDK version 10 for API routes

Similarly for the admin SDK, we create a similar function, but we also handle a check against the number of apps being initialized.

// initFirebaseAdmin.ts

import {
  AppOptions,
  cert,
  getApp,
  getApps,
  initializeApp,
  ServiceAccount,
} from "firebase-admin/app";
import { getAuth } from "firebase-admin/auth";

const credentials: ServiceAccount = {
  projectId: process.env.projectID,
  privateKey: process.env.privateKey.replace(/\\n/g, "\n"),
  clientEmail: process.env.clientEmail,
};

const options: AppOptions = {
  credential: cert(credentials),
  databaseURL: process.env.databaseURL,
};

function createFirebaseAdminApp(config: AppOptions) {
  if (getApps().length === 0) {
    return initializeApp(config);
  } else {
    return getApp();
  }
}

const firebaseAdmin = createFirebaseAdminApp(options);
export const adminAuth = getAuth(firebaseAdmin);
Enter fullscreen mode Exit fullscreen mode

Now we can make use of adminAuth in any API route handler to manage authenticated users.

And that's really it!

Top comments (1)

Collapse
 
tettoffensive profile image
Stuart Tett

Thanks for the update. I still had my code like v8 and while it worked sometimes, occasionally the length check failed and the didn't get initialized even though it needed to be. Works with the v9 update.