angularfire icon indicating copy to clipboard operation
angularfire copied to clipboard

Using with Angular 17 SSR -> document is not defined on initializeAppCheck

Open jjgriff93 opened this issue 1 year ago • 3 comments

Version info

Angular: 17.0.8

Firebase: 10.7.1

AngularFire: 17.0.0

Other (e.g. Ionic/Cordova, Node, browser, operating system): Node 18, Ionic 7, MacOS

How to reproduce these conditions

Steps to set up and reproduce

  1. New Angular 17 project
  2. ng add @angular/fire@17
  3. ng add @angular/ssr
  4. Set up App Check as per https://github.com/angular/angularfire/blob/master/docs/app-check.md
  5. ng build

Debug output

⠇ Building...
ReferenceError: document is not defined
    at makeDiv (/app/.angular/prerender-root/node_modules/@firebase/app-check/dist/esm/index.esm2017.js:1119:26)
    at initializeV3 (/app/.angular/prerender-root/node_modules/@firebase/app-check/dist/esm/index.esm2017.js:1064:19)
    at _ReCaptchaV3Provider.initialize (/app/.angular/prerender-root/node_modules/@firebase/app-check/dist/esm/index.esm2017.js:1255:9)
    at _activate (/app/.angular/prerender-root/node_modules/@firebase/app-check/dist/esm/index.esm2017.js:1543:20)
    at initializeAppCheck (/app/.angular/prerender-root/node_modules/@firebase/app-check/dist/esm/index.esm2017.js:1498:5)
    at <anonymous> (app/.angular/prerender-root/c56c3be0-e454-4b23-bf7d-d028ecf276ec/node_modules/@angular/fire/fesm2022/angular-fire.mjs:216:44)
    at <anonymous> (/app/.angular/prerender-root/c56c3be0-e454-4b23-bf7d-d028ecf276ec/node_modules/@angular/fire/fesm2022/angular-fire.mjs:148:57)
    at _ZoneDelegate.invoke (/app/.angular/prerender-root/node_modules/zone.js/fesm2015/zone.js:368:26)
    at _Zone.run (/app/.angular/prerender-root/node_modules/zone.js/fesm2015/zone.js:129:43)
    at _NgZone.runOutsideAngular (/app/.angular/prerender-root/node_modules/@angular/core/fesm2022/core.mjs:1461
An unhandled exception occurred: document is not defined

Expected behavior

AngularFire should check if rendering on a browser before calling App Check code and RecaptchaV3 (which relies on document being available)

Actual behavior

No check is done, so when providing App Check, this above error occurs as soon as pre-rendering on the server happens and document is accessed but isn't available due to not running in a browser

jjgriff93 avatar Jan 06 '24 01:01 jjgriff93

It's older Angular but here's an example on how to use AppCheck with SSR https://github.com/angular/angularfire/blob/8157744c53e378c379b0bdedd480332b997f741a/samples/advanced/src/app/app.module.ts#L46

jamesdaniels avatar Jan 06 '24 02:01 jamesdaniels

Thanks James, I've managed to work around it for now by using isPlatformServer()

provideAppCheck(() => {
      // Don't initialise AppCheck if running in server
      // Workaround for https://github.com/angular/angularfire/issues/3488
      const platformId = inject(PLATFORM_ID);
      if (isPlatformServer(platformId)) {
        return;
      }

      let provider: CustomProvider | ReCaptchaV3Provider;

      // Initialise AppCheck natively if running on iOS or Android
      if (Capacitor.isNativePlatform()) {
        // Set the web debug token to false if running on native
        globalThis.FIREBASE_APPCHECK_DEBUG_TOKEN = false;
        provider = new CustomProvider({
          getToken: () =>
            FirebaseAppCheck.getToken({
              forceRefresh: true
            }) as Promise<AppCheckToken>
        });
      } else {
        // Or use ReCAPTCHAv3 if running in web
        provider = new ReCaptchaV3Provider(
          environment.firebase.recaptchaSiteKey
        );
      }

      // Initialise AngularFire app check using provider
      const appCheck = initializeAppCheck(getApp(), {
        provider: provider
      });
      return appCheck;
    }),

Although now hitting a similar issue with Performance which the above doesn't seem to work for, so will raise that as a separate ticket

jjgriff93 avatar Jan 06 '24 14:01 jjgriff93

Raised in #3489

jjgriff93 avatar Jan 06 '24 15:01 jjgriff93