Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

requiring firebaseUI - window is not defined

I have a JS file and I'm trying to use Firebase.

This is the part that causes the issue (specifically firebaseUI)

var firebase = require('firebase');
var firebaseui = require('firebaseui');

I didn't forget to install both:

npm install firebase --save
npm install firebaseui --save

But when I run the node I get:

/Users/nimrodshai/Documents/Projects/WeatherJS/node_modules/firebaseui/dist/npm.js:30
componentHandler["register"]=componentHandler.register;componentHandler["downgradeElements"]=componentHandler.downgradeElements;window.componentHandler=componentHandler;window["componentHandler"]=componentHandler;
                                                                                                                                ^

ReferenceError: window is not defined
    at /Users/nimrodshai/Documents/Projects/WeatherJS/node_modules/firebaseui/dist/npm.js:30:129
    at Object.<anonymous> (/Users/nimrodshai/Documents/Projects/WeatherJS/node_modules/firebaseui/dist/npm.js:420:460)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:22:18)
    at Object.<anonymous> (/Users/nimrodshai/Documents/Projects/WeatherJS/JS/server.js:8:18)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3)

If I remove the firebaseUI line, it's all good.

What should I do?

like image 676
Nimrod Shai Avatar asked Jan 15 '19 09:01

Nimrod Shai


2 Answers

I also stumbled across this issue. MeanMan's answer really helped me, but there are two things that needs to be considered:

  • useEffect must not accept an async function, as it returns a promise, which useEffect doesn't support. more info
  • we should take into account that there might be already an instance of AuthUI running, and in that case we should not be creating a new one. Otherwise the error Error: An AuthUI instance already exists for the key "[DEFAULT]" might appear. more info

The final component looks like this (using TypeScript)

import React, { FC, useCallback, useEffect } from "react";
import firebase from "firebase";

interface Props {
  firebaseClient: typeof firebase;
  config: firebaseui.auth.Config;
}

const FirebaseUiLogin: FC<Props> = ({ firebaseClient, config }) => {
  const loadFirebaseui = useCallback(async () => {
    const firebaseui = await import("firebaseui");
    const firebaseUi =
      firebaseui.auth.AuthUI.getInstance() ||
      new firebaseui.auth.AuthUI(firebaseClient.auth());
    firebaseUi.start("#firebaseui-auth-container", config);
  }, [firebaseClient, config]);

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

  return <div id="firebaseui-auth-container"></div>;
};

export default FirebaseUiLogin;
like image 185
Tevu Avatar answered Oct 04 '22 17:10

Tevu


Firebaseui is meant to run in browser and expects window object to be loaded, if you are using SSR(like next.js) or to be more specific if the code runs in server side and not in the browser it won't find the window object.

I landed here when I was trying to integrate firebaseui with next js, I finally was able to solve the problem using dynamic imports.

Find below the code for Login component which loaded the firebase UI.

const LoginFinal = () => {
  useEffect(async () => {
    
    // delay the import until window object is ready
    const firebaseui = await import("firebaseui");
    const ui = new firebaseui.auth.AuthUI(auth);
    ui.start("#firebaseui", {
      signInOptions: [firebaseAuthObject.EmailAuthProvider.PROVIDER_ID],
    });
   
  });

  return <div id="firebaseui" />;
};
like image 37
MeanMan Avatar answered Oct 04 '22 17:10

MeanMan