The Wayback Machine - https://web.archive.org/web/20220711201621/https://github.com/angular/angularfire/issues/3181
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSR => @firebase/auth: Auth (9.6.8): INTERNAL ASSERTION FAILED: Expected a class definition #3181

Open
ohabash opened this issue Mar 17, 2022 · 19 comments

Comments

@ohabash
Copy link

@ohabash ohabash commented Mar 17, 2022

Firebase:

"firebase": "^9.6.8",

AngularFire:

Angular CLI: 13.3.0
Node: 14.16.0
Package Manager: npm 6.14.11
OS: darwin x64

Angular: 13.2.5
... animations, cdk, common, compiler, compiler-cli, core, forms
... language-service, material, platform-browser
... platform-browser-dynamic, platform-server, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1303.0
@angular-devkit/build-angular   13.0.4
@angular-devkit/core            13.3.0
@angular-devkit/schematics      13.3.0
@angular/cli                    13.3.0
@angular/fire                   7.2.1
@angular/google-maps            13.3.0
@nguniversal/builders           13.0.2
@nguniversal/express-engine     13.0.2
@schematics/angular             13.3.0
ng-packagr                      13.2.1
rxjs                            6.6.7
typescript                      4.5.5

How to reproduce these conditions

  1. run habitat-commons:serve-ssr:development
  2. in my app browser and ssr server will build fine
  3. start ssr server node dist/apps/habitat-commons/server/main.js
  4. make a request to this server
  5. see errors below

First Error

 @firebase/auth: Auth (9.6.8): INTERNAL ASSERTION FAILED: Expected a class definition
Error: INTERNAL ASSERTION FAILED: Expected a class definition
    at debugFail (test_app/dist/apps/habitat-commons/server/main.js:317691:9)
    at debugAssert (test_app/dist/apps/habitat-commons/server/main.js:317704:5)
    at Module._getInstance (test_app/dist/apps/habitat-commons/server/main.js:317728:3)
    at new CompatPopupRedirectResolver (test_app/dist/apps/habitat-commons/server/main.js:315880:81)
    at _getInstance (test_app/dist/apps/habitat-commons/server/main.js:317736:14)
    at AuthImpl._initializeWithPersistence (test_app/dist/apps/habitat-commons/server/main.js:320082:37)
    at _initializeAuthInstance (test_app/dist/apps/habitat-commons/server/main.js:317817:8)
    at test_app/dist/apps/habitat-commons/server/main.js:325294:7
    at Component.instanceFactory (test_app/dist/apps/habitat-commons/server/main.js:325297:7)
    at Provider.getOrInitializeService (test_app/dist/apps/habitat-commons/server/main.js:327833:33)

i looked into the _getInstance mentioned in the callstack. it takes an arg that should be a class instance. hence the error.

Here is what _getInstance looked like in my ssr bootstrap (main.js)

function _getInstance(cls) {
  console.log('**((_getInstance 0))**', cls)
  debugAssert(cls instanceof Function, 'Expected a class definition');
  let instance = instanceCache.get(cls);

  if (instance) {
    debugAssert(instance instanceof cls, 'Instance stored in cache mismatched with class');
    return instance;
  }

  instance = new cls();
  instanceCache.set(cls, instance);
  return instance;
}

The log i added(see above) revealed that an error instead of a class was passed in the 3 rd time.see out put below

**((_getInstance 0))** [class InMemoryPersistence] { type: 'NONE' }
**((_getInstance 0))** [class CompatPopupRedirectResolver]
**((_getInstance 0))** FirebaseError: Firebase: Error (auth/operation-not-supported-in-this-environment).
    at createErrorInternal (test_app/dist/apps/habitat-commons/server/main.js:317665:38)
    at _createError (test_app/dist/apps/habitat-commons/server/main.js:317640:10)
    at Module.2485 (test_app/dist/apps/habitat-commons/server/main.js:325381:29)
    at __webpack_require__ (test_app/dist/apps/habitat-commons/server/main.js:545206:42)
    at Module.32562 (test_app/dist/apps/habitat-commons/server/main.js:325547:76)
    at __webpack_require__ (test_app/dist/apps/habitat-commons/server/main.js:545206:42)
    at Module.70092 (test_app/dist/apps/habitat-commons/server/main.js:315550:81)
    at __webpack_require__ (test_app/dist/apps/habitat-commons/server/main.js:545206:42)
    at Module.55776 (test_app/dist/apps/habitat-commons/server/main.js:500158:79)
    at __webpack_require__ (test_app/dist/apps/habitat-commons/server/main.js:545206:42) {
  code: 'auth/operation-not-supported-in-this-environment',
  customData: {}
}
[2022-03-17T20:12:59.002Z]  @firebase/auth: Auth (9.6.8): INTERNAL ASSERTION FAILED: Expected a class definition
ERROR Error: INTERNAL ASSERTION FAILED: Expected a class definition

of course all my servers and test requests are on local host...Do you know anything that can help me understand either error

@firebase/auth: Auth (9.6.8): INTERNAL ASSERTION FAILED: Expected a class definition

or

Firebase: Error (auth/operation-not-supported-in-this-environment)

Expected behavior

I expected to send a universal rendered view to the browser

Actual behavior

Firebase auth prevents universal from performing its task.

@google-oss-bot
Copy link

@google-oss-bot google-oss-bot commented Mar 17, 2022

This issue does not seem to follow the issue template. Make sure you provide all the required information.

@ohabash
Copy link
Author

@ohabash ohabash commented Mar 17, 2022

There seems to be a resolve in here. however I dont know how to apply it to my @angular/fire env

firebase/firebase-js-sdk#5475 (comment)

@ProSugu
Copy link

@ProSugu ProSugu commented Mar 19, 2022

any workaround for the above issue ?

@ohabash
Copy link
Author

@ohabash ohabash commented Mar 20, 2022

None that i have found but still working on it.

@senior-webdeveloper
Copy link

@senior-webdeveloper senior-webdeveloper commented Mar 20, 2022

Hello, hope you are doing well.
I have same issue, If you found the solution, please let me know.
thanks

@ohabash
Copy link
Author

@ohabash ohabash commented Mar 21, 2022

firebase/firebase-js-sdk#5475 (comment)

This seems to be the best lead however i have not figured out how to implement with @angular/fire

We had to use scully. But I will get start debugging this again soon.

@yharaskrik
Copy link

@yharaskrik yharaskrik commented May 18, 2022

Also encountering this. I tried to use inMemoryPersistence but I still received the same error.

@Santoshah
Copy link

@Santoshah Santoshah commented Jun 1, 2022

I am encountering same issue. Any solution yet ?

I tried creating custom-webpack.config and added those resolve option but still it didn't work.

webpack.config.js

module.exports = {
  resolve: {
    mainFields: ["browser", "main"],
  },
};
@kamstob
Copy link

@kamstob kamstob commented Jun 2, 2022

"firebase": "^9.8.1",
I also struggle with this problem ... :/

@yharaskrik
Copy link

@yharaskrik yharaskrik commented Jun 2, 2022

This will solve the issue for you if you are getting it when server side rendering (we are using Angular Universal)

provideAuth(() => {
            /*
             * This is a hack to get around the issue described in this thread:
             * https://github.com/firebase/firebase-js-sdk/issues/5475
             *
             * It has not been fixed and the webpack trick both did not work nor
             * was it simple to implement. What this does is it checks to see if it
             * is being SSR'd, if it is not then initialize firebase normally,
             * if it is then just "gets" the auth, which is essential a noop.
             */
            if (typeof document !== 'undefined') {
                return initializeAuth(getApp(), {
                    persistence: browserLocalPersistence,
                    popupRedirectResolver: browserPopupRedirectResolver,
                });
            }
            return getAuth(getApp());
        }),
@kamstob
Copy link

@kamstob kamstob commented Jun 3, 2022

provideAuth

Thank you. May I ask you what the implementation for Angular 13 / Angularfire 7.3.0 should look like?

@yharaskrik
Copy link

@yharaskrik yharaskrik commented Jun 3, 2022

provideAuth

Thank you. May I ask you what the implementation for Angular 13 / Angularfire 7.3.0 should look like?

What I shared above is working for me with angular 13 and angularfire 7

@Santoshah
Copy link

@Santoshah Santoshah commented Jun 7, 2022

Where this initializeAuth has to be mentioned ? I tried replacing all getAuth with this but it throws error saying initializeAuth can only be intialize one.

@yharaskrik
Copy link

@yharaskrik yharaskrik commented Jun 7, 2022

Where this initializeAuth has to be mentioned ? I tried replacing all getAuth with this but it throws error saying initializeAuth can only be intialize one.

In our AppModule where firebase is initialized. You should only replace the initialization not all getauth calls.

image

@Santoshah
Copy link

@Santoshah Santoshah commented Jun 11, 2022

Where this initializeAuth has to be mentioned ? I tried replacing all getAuth with this but it throws error saying initializeAuth can only be intialize one.

In our AppModule where firebase is initialized. You should only replace the initialization not all getauth calls.

For me still not working. Any help ?
image

import { AngularFireModule } from "@angular/fire/compat/";
import { AngularFireAuthModule } from "@angular/fire/compat/auth";
import { AngularFirestoreModule } from "@angular/fire/compat/firestore";
import { AngularFireMessagingModule } from '@angular/fire/compat/messaging';
import { AngularFireAuthGuardModule } from '@angular/fire/compat/auth-guard';
import { environment } from "../environments/environment";
import { provideFirebaseApp } from '@angular/fire/app';
import { provideAuth } from '@angular/fire/auth';
import { browserLocalPersistence, browserPopupRedirectResolver, getAuth, initializeAuth } from 'firebase/auth';

const { version: appVersion}=require('../../package.json');
const modules = []
if(environment.production) {
    modules.push(NgxHotjarModule.forRoot(environment.hotJarId, appVersion))
}
const firebaseApp = initializeApp(environment.firebase);
initializeFirestore(firebaseApp, { experimentalForceLongPolling: true });

const routerConfig: ExtraOptions = {
    scrollPositionRestoration: 'enabled',
    preloadingStrategy       : PreloadAllModules
};

@NgModule({
    declarations: [
        AppComponent,
        PreAssesmentComponent,
    ],
    imports: [
        BrowserModule.withServerTransition({ appId: 'serverApp' }),
        HttpClientModule,
        BrowserAnimationsModule,
        ReactiveFormsModule,
        FormsModule,
        //RouterModule.forRoot(appRoutes, routerConfig),
        AppRoutingModule,
        UserModule,
        CoreModule,
        LayoutModule,
        provideFirebaseApp(()=>initializeApp(environment.firebase)),
        provideAuth(() => {
            if (typeof document !== 'undefined') {
                return initializeAuth(getApp(), {
                    persistence: browserLocalPersistence,
                    popupRedirectResolver: browserPopupRedirectResolver,
                });
            }
            return getAuth(getApp());
        }),
        AngularFireModule.initializeApp(environment.firebase),
        AngularFireAuthGuardModule,
        AngularFireMessagingModule,
        AngularFireAuthModule,
        AngularFirestoreModule,
    ],

    bootstrap   : [
        AppComponent
    ],


})
export class AppModule
{
}

@yharaskrik
Copy link

@yharaskrik yharaskrik commented Jun 11, 2022

Where this initializeAuth has to be mentioned ? I tried replacing all getAuth with this but it throws error saying initializeAuth can only be intialize one.

In our AppModule where firebase is initialized. You should only replace the initialization not all getauth calls.

For me still not working. Any help ?
image

import { AngularFireModule } from "@angular/fire/compat/";
import { AngularFireAuthModule } from "@angular/fire/compat/auth";
import { AngularFirestoreModule } from "@angular/fire/compat/firestore";
import { AngularFireMessagingModule } from '@angular/fire/compat/messaging';
import { AngularFireAuthGuardModule } from '@angular/fire/compat/auth-guard';
import { environment } from "../environments/environment";
import { provideFirebaseApp } from '@angular/fire/app';
import { provideAuth } from '@angular/fire/auth';
import { browserLocalPersistence, browserPopupRedirectResolver, getAuth, initializeAuth } from 'firebase/auth';

const { version: appVersion}=require('../../package.json');
const modules = []
if(environment.production) {
    modules.push(NgxHotjarModule.forRoot(environment.hotJarId, appVersion))
}
const firebaseApp = initializeApp(environment.firebase);
initializeFirestore(firebaseApp, { experimentalForceLongPolling: true });

const routerConfig: ExtraOptions = {
    scrollPositionRestoration: 'enabled',
    preloadingStrategy       : PreloadAllModules
};

@NgModule({
    declarations: [
        AppComponent,
        PreAssesmentComponent,
    ],
    imports: [
        BrowserModule.withServerTransition({ appId: 'serverApp' }),
        HttpClientModule,
        BrowserAnimationsModule,
        ReactiveFormsModule,
        FormsModule,
        //RouterModule.forRoot(appRoutes, routerConfig),
        AppRoutingModule,
        UserModule,
        CoreModule,
        LayoutModule,
        provideFirebaseApp(()=>initializeApp(environment.firebase)),
        provideAuth(() => {
            if (typeof document !== 'undefined') {
                return initializeAuth(getApp(), {
                    persistence: browserLocalPersistence,
                    popupRedirectResolver: browserPopupRedirectResolver,
                });
            }
            return getAuth(getApp());
        }),
        AngularFireModule.initializeApp(environment.firebase),
        AngularFireAuthGuardModule,
        AngularFireMessagingModule,
        AngularFireAuthModule,
        AngularFirestoreModule,
    ],

    bootstrap   : [
        AppComponent
    ],


})
export class AppModule
{
}

You are still importing all of the angular fire modules from /compat. You should remove all of those and just use the provider functions introduced in v9.

(Except the auth guard module, just make sure you import that from that path that is not /compat).

These are the only Imports we have for firebase in our application:

import { getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
import { browserLocalPersistence, getAuth, initializeAuth, provideAuth } from '@angular/fire/auth';
import { AuthGuardModule } from '@angular/fire/auth-guard';
import { getMessaging, provideMessaging } from '@angular/fire/messaging';
import { browserPopupRedirectResolver } from '@firebase/auth';
import type { Environment } from '@trellis/shared/environment/client';

export function provideFirebase(environment: Environment) {
    return [
        provideFirebaseApp(() => initializeApp(environment.firebase)),
        provideAuth(() => {
            /*
             * This is a hack to get around the issue described in this thread:
             * https://github.com/firebase/firebase-js-sdk/issues/5475
             *
             * It has not been fixed and the webpack trick both did not work nor
             * was it simple to implement. What this does is it checks to see if it
             * is being SSR'd, if it is not then initialize firebase normally,
             * if it is then just "gets" the auth, which is essential a noop.
             */
            if (typeof document !== 'undefined') {
                return initializeAuth(getApp(), {
                    persistence: browserLocalPersistence,
                    popupRedirectResolver: browserPopupRedirectResolver,
                });
            }
            return getAuth(getApp());
        }),
        AuthGuardModule,
        provideMessaging(() => getMessaging()),
    ];
}
@Santoshah
Copy link

@Santoshah Santoshah commented Jun 29, 2022

Thanks @yharaskrik. It worked fine with modular firebase 9

We were in a process to update our firebase from 8 to 9. We had manage to remove compat version and run our application on modular version. Its working fine with Angular Universal + Angular version 14 and firebase 9

@senior-webdeveloper
Copy link

@senior-webdeveloper senior-webdeveloper commented Jun 29, 2022

@aladjikane
Copy link

@aladjikane aladjikane commented Jul 1, 2022

Qui a une solution SSR 13 j'ai cauchemar pour ce probleme

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
8 participants