Daryl Wong
Daryl Wong

Reputation: 2443

NextJS: How to correctly add firebase analytics to NextJS app

I have a react/nextjs app and I have firebase.js as follow:

import firebase from 'firebase/app'
import 'firebase/auth'
import 'firebase/analytics'
import 'firebase/firestore'

const firebaseConfig = {
  apiKey: '...'
}
try {
  firebase.initializeApp(firebaseConfig)
  firebase.analytics()
} catch (err) {
  if (!/already exists/.test(err.message)) {
    console.error('Firebase initialization error', err.stack)
  }
}

export default firebase

I kept getting

Firebase initialization error ReferenceError: navigator is not defined

after adding analytics to the firebase.js file. What is the correct way to add analytics to the app?

Upvotes: 13

Views: 15029

Answers (7)

Sir hennihau
Sir hennihau

Reputation: 1784

The top answer alone didn't solve it somehow for me. This is how I did it in the end:

import { initializeApp } from "firebase/app";
import { getAnalytics, logEvent, isSupported } from "firebase/analytics";


const firebaseConfig = {
  // ...
};

const app = initializeApp(firebaseConfig);

const analytics = isSupported().then((isSupported) => (isSupported ? getAnalytics(app) : null));

export const logCustomEvent = async (event: MyCustomEventType | string) => {
    if (!analytics) return;

    logEvent(getAnalytics(), event, { platform: "web" });
};

and usage within a component would be like

logCustomEvent("my_awesome_event")

It was important to use getAnalytics() within logEvent, otherwise I got an error.

Upvotes: 0

Alex Mendes
Alex Mendes

Reputation: 71

Using top-level await

import { initializeApp } from "firebase/app";
import { getAnalytics, isSupported } from "firebase/analytics";

const firebaseConfig = {
  ... 
};

const firebaseApp = initializeApp(firebaseConfig);

const analytics = await isSupported() ? getAnalytics(firebaseApp) : null

export { analytics }

And then using logEvent from firebase/analytics

import { logEvent } from "firebase/analytics";
import { analytics } from "../../firebase/init";

  useEffect(() => {

    analytics && logEvent(analytics, 'page_view', {
      page_title: "/",
      page_path: "/",
    });

  }, [])

Upvotes: 1

Jamal Eddine Naamani
Jamal Eddine Naamani

Reputation: 456

Using firebase V 9.16 this how I solved the issue

import { initializeApp } from "firebase/app";
import { getAnalytics, isSupported } from "firebase/analytics";
import { getFirestore } from "firebase/firestore"
const firebaseConfig = {
    ...
};
let app; let analytics; let db
if(typeof window != undefined){
  app = initializeApp(firebaseConfig);
  analytics = isSupported().then(yes => yes ? getAnalytics(app) : null);
  db = getFirestore(app)
}


export {app, analytics, db}

In _app.js I import analytics and i use useEffect like

useEffect(() => {
    analytics;
  }, [])

Upvotes: 2

user11857517
user11857517

Reputation:

import { getAnalytics, isSupported } from "firebase/analytics";

const analytics = isSupported().then(yes => yes ? getAnalytics(app) : null);

Upvotes: 40

Daryl Wong
Daryl Wong

Reputation: 2443

I just updated my firebase to version 9 and this error is not seen.

Update to version 9 could be a solution to this.

But for version 9, there are some changes in firebase declaration.

import firebase from 'firebase/compat/app'
import 'firebase/compat/auth'
import 'firebase/compat/firestore'

Upvotes: 0

Muhammad Shahzad Ali
Muhammad Shahzad Ali

Reputation: 149

Try this one

import firebase from "firebase/app"
import "firebase/auth"
import "firebase/firestore"
import "firebase/storage"
import "firebase/analytics"

const firebaseConfig = {
  apiKey: process.env.NEXT_PUBLIC_API_KEY,
  authDomain: process.env.NEXT_PUBLIC_AUTH_DOMAIN,
  projectId: process.env.NEXT_PUBLIC_PROJECT_ID,
  appId: process.env.NEXT_PUBLIC_APP_ID,
  storageBucket: process.env.NEXT_PUBLIC_STORAGE_BUCKET,
  messagingSenderId: process.env.NEXT_PUBLIC_MESSAGING_SENDER_ID,
  measurementId: process.env.NEXT_PUBLIC_MEASUREMENT_ID,
}
if (!firebase.apps.length) {
  firebase.initializeApp(firebaseConfig)
}

// Auth export
export const auth = firebase.auth()

// Firestore exports
export const firestore = firebase.firestore()
export const serverTimestamp = firebase.firestore.FieldValue.serverTimestamp
export const fbTimestamp = firebase.firestore.Timestamp
export const fromMillis = firebase.firestore.Timestamp.fromMillis
export const increment = firebase.firestore.FieldValue.increment

// Storage exports
export const storage = firebase.storage()

export const analytics = () => {
  if (typeof window !== "undefined") {
    return firebase.analytics()
  } else {
    return null
  }
}
export default firebase

Upvotes: 8

Travis
Travis

Reputation: 207

ReferenceError: navigator is not defined because there is no window object present during the server-side rendering of the Nextjs application.

Try:

if(typeof window != undefined){
     firebase.analytics()
}

Upvotes: 1

Related Questions