Using firebaseui with Angular Universal - ReferenceError: window is not defined

59 Views Asked by At

I have an Angular 16 app, using Angular Fire, firebaseui and I have recently installed Angular Universal.

Whenever I run npm run dev:ssr to enable SSR I receive this error -

./node_modules/dialog-polyfill/dialog-polyfill.js:4
  var supportCustomEvent = window.CustomEvent;
                           ^


ReferenceError: window is not defined
    at <anonymous> (./node_modules/dialog-polyfill/dialog-polyfill.js:4:28)
    at Object.44252 (./node_modules/dialog-polyfill/dialog-polyfill.js:738:2)
    at __webpack_require__ (./webpack/bootstrap:19:1)
    at Module.73697 (./node_modules/express/node_modules/serve-static/index.js:210:1)
    at __webpack_require__ (./webpack/bootstrap:19:1)
    at Module.10388 (./src/app/components/home/home.component.html:46:10)
    at __webpack_require__ (./webpack/bootstrap:19:1)
    at Module.11838 (./server.ts:74:35)
    at __webpack_require__ (./webpack/bootstrap:19:1)
    at Module.50041 (./src/app/app.component.html:3:8)

Node.js v20.9.0
A server error has occurred.
node exited with 1 code.

The dialog-polyfill package is brought in as a dependency for firebaseui. It is not used anywhere else.

I have tried to mitigate against this issue using platformBrowser and also the domino package but am still facing the same error. Any ideas?

login.component.ts

isBrowser: boolean = false;
constructor(
    @Inject(PLATFORM_ID) private platformId: Object
  ) {
    this.isBrowser = isPlatformBrowser(platformId);
   }

ngOnInit(): void {
    if (isPlatformBrowser(this.platformId)) {
      if (!this.ui) {
        this.ui = new firebaseui.auth.AuthUI(this.auth as any);
      }

      const uiConfig: firebaseui.auth.Config = {
        signInOptions: [
          EmailAuthProvider.PROVIDER_ID,
        ],
        signInSuccessUrl: '/',
        credentialHelper: firebaseui.auth.CredentialHelper.NONE,
        tosUrl: '/privacy-policy',
        privacyPolicyUrl: '/privacy-policy',
        callbacks: {
          signInSuccessWithAuthResult: (authResult: { user: User | null; }, redirectUrl: any) => {
            this.onLoginSuccessful(authResult.user);
            return false;
          },
          uiShown: () => {
            const loader = document.getElementById('loader');
            if (loader) {
              loader.style.display = 'none';
            }
          },
          signInFailure: (error: any) => {
            console.error(error);
            alert('Sign-in failed. Please try again with correct username & password.');
            return Promise.resolve();
          }
        },
        signInFlow: 'popup',
        autoUpgradeAnonymousUsers: true,
        siteName: 'My App'
      };

      this.ui.start('#firebaseui-auth-container', uiConfig);

      this.auth.onAuthStateChanged((user: any) => {
        if (!user && this.ui.isPendingRedirect()) {
          this.ui.start('#firebaseui-auth-container', uiConfig);
        }
      });
    }

  }

login.component.html

<div *ngIf="isBrowser" id="firebaseui-auth-container" class="auth-container">

server.ts

// domino to create dom in server 
const domino = require('domino');
const fs = require('fs');
const path = require('path');

// Use the browser index.html as template for the mock window
const template = fs
  .readFileSync(path.join(join(process.cwd(), 'dist/<PROJECTNAME>/browser'), 'index.html'))
  .toString();

// Shim for the global window and document objects.
const window = domino.createWindow(template);
global['window'] = window;
global['document'] = window.document;

package.json

"@angular/fire": "~7.6.1",
"@nguniversal/express-engine": "^16.2.0",
"domino": "^2.1.6",
"firebase": "^9.23.0",
"firebaseui": "^6.1.0",

I have rebuilt the server.ts file using npm run build:ssr after making and saving the changes.

1

There are 1 best solutions below

0
Robgit28 On

I haven't seen it explicitly stated but what I've senn implicity implied stated, by other libraries and the Firebaseui GitHub repo is that Firebaseui does not work with SSR. I would suggest using another library that is compatible with your Angular app or writing the interface and TS code yourself, although make sure you monitor for security concerns.