Home > OS >  Window is not defined while using firebase auth in next.js
Window is not defined while using firebase auth in next.js

Time:10-27

Following code is from firebaseConfig.js:

import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";
import { getAuth } from "firebase/auth";

const firebaseConfig = {
  //credentials//
};
export const app = initializeApp(firebaseConfig);
export const analytics=getAnalytics(app)
export const authentication=getAuth(app);

Following code is from index.js:

export default function Home() {
  const auth = getAuth();
  const generateRecaptcha=()=>{
    
    window.recaptchaVerifier = new RecaptchaVerifier('recaptcha-container', {}, authentication);

  }
  window.recaptchaVerifier = new RecaptchaVerifier('recaptcha-container', {}, auth);
  const getOTP=()=>{
    generateRecaptcha()
  }

I am getting error:

ReferenceError: window is not defined

error window screenshot

After removing export getAnyalytics, I am still getting the same error but at window.recaptchaVerifier function in index.js.

Also please tell me the use of getAnalytics.

CodePudding user response:

getAnalytics() will instantiate an instance of Firebase Analytics that you can use to log events throughout your app.

The solution for me when using analytics was to create a provider as follows:

FirebaseTrackingProvider.tsx


export const FirebaseTrackingProvider = (props: {children: ReactNode}) => {
  const router = useRouter();
  const [analytics, setAnalytics] = useState(null);

  useEffect(() => {
    setAnalytics(getAnalytics(firebaseApp));
    if (analytics) {
      setAnalyticsCollectionEnabled(analytics, true);
    }

    const handleRouteChange = (url: string) => {
      if (!analytics) {
        return;
      }
      logEvent(analytics, 'page_view', {
        page_location: url,
        page_title: document?.title,
      });
      setCurrentScreen(analytics, document.title ?? 'Undefined');
    };

    router.events.on('routeChangeStart', handleRouteChange);

    return () => {
      router.events.off('routeChangeStart', handleRouteChange);
    };
  }, [analytics, router.events]);

  return <FirebaseContext.Provider value={analytics}>{props.children}</FirebaseContext.Provider>;
};

I can then consume it different pages or components:

const analytics = useContext(FirebaseContext);

// in sign up flow

logEvent(analytics, 'sign_up', {
  uid: data.uid,
  email: data.email,
});

Regarding the recapture erorr: NextJS will first attempt to render serverside content if there is any, before bootstrapping the react application. This means that the window has not been defined yet when you are trying to instantiate a new RecaptchaVerifier instance. You can use an if(window) to make sure you are only doing so when the window is instantiated, or alternatively, you can run a useEffect as follows:

useEfect(() => {

  // This wont change on re renders
  let completed = false;

  if (!completed && window){
    // recaptca instantiation
    completed = true;
  }

}, [window])
  • Related