Lazy loading FirebaseUIModule
See original GitHub issueUsing custom modules that are being lazy loaded and that import FirebaseUIModule
results in Error: An AuthUI instance already exists for the key "[DEFAULT]" Error: An AuthUI instance already exists for the key "[DEFAULT]
error.
Consider this scenario
app.module.ts
import { environment } from '../environments/environment';
import { AppComponent } from './app.component';
import { AngularFireModule } from 'angularfire2';
import { AngularFireAuthModule } from 'angularfire2/auth';
import { FirebaseUIModule } from 'firebaseui-angular';
@NgModule({
imports: [
BrowserModule,
AngularFireModule.initializeApp(environment.firebaseConfig),
AngularFireAuthModule,
FirebaseUIModule.forRoot(environment.firebaseUiConfig),
AppRouting
],
declarations: [
AppComponent
],
providers: [ ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
app.routing.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [
{ path: 'login', loadChildren: 'app/login/login.module#LoginModule' },
{ path: 'register', loadChildren: 'app/register/register.module#RegisterModule' }
@NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ],
})
export class AppRouting { }
Now the login and register feature. Each having their own module.
login.module.ts
import { environment } from '../../environments/environment';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { FirebaseUIModule } from 'firebaseui-angular';
import { LoginComponent } from './login.component';
@NgModule({
imports: [
CommonModule,
FormsModule,
FirebaseUIModule
],
declarations: [
LoginComponent
],
exports: [ LoginComponent ],
})
export class LoginModule { }
register.module.ts
import { environment } from '../../environments/environment';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { FirebaseUIModule } from 'firebaseui-angular';
import { RegisterComponent } from './register.component';
@NgModule({
imports: [
CommonModule,
FormsModule,
FirebaseUIModule
],
declarations: [
RegisterComponent
],
exports: [ RegisterComponent ],
})
export class RegisterModule { }
When the app redirects to either /login
or /register
for the first time Firebase UI is presented without any problem. If the first visited path is visited next time (without visiting the other one) UI is also presented without any problem (e.g. user visits /login
consecutively several times). On the other hand if the second visited path is not same as the first visited path (e.g. user visits first /login
and then visits /register
) the error is thrown.
Full error message
ERROR Error: Uncaught (in promise): Error: An AuthUI instance already exists for the key "[DEFAULT]"
Error: An AuthUI instance already exists for the key "[DEFAULT]"
at new Dl (npm.js:334)
at new FirebaseUIService (index.js:15)
at _createClass (core.es5.js:9520)
at _createProviderInstance$1 (core.es5.js:9492)
at resolveNgModuleDep (core.es5.js:9477)
at NgModuleRef_.webpackJsonp.../../../core/@angular/core.es5.js.NgModuleRef_.get (core.es5.js:10569)
at resolveDep (core.es5.js:11072)
at createClass (core.es5.js:10931)
at createDirectiveInstance (core.es5.js:10756)
at createViewNodes (core.es5.js:12197)
at new Dl (npm.js:334)
at new FirebaseUIService (index.js:15)
at _createClass (core.es5.js:9520)
at _createProviderInstance$1 (core.es5.js:9492)
at resolveNgModuleDep (core.es5.js:9477)
at NgModuleRef_.webpackJsonp.../../../core/@angular/core.es5.js.NgModuleRef_.get (core.es5.js:10569)
at resolveDep (core.es5.js:11072)
at createClass (core.es5.js:10931)
at createDirectiveInstance (core.es5.js:10756)
at createViewNodes (core.es5.js:12197)
at resolvePromise (zone.js:795)
at resolvePromise (zone.js:766)
at zone.js:844
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:425)
at Object.onInvokeTask (core.es5.js:3881)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)
at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask (zone.js:192)
at drainMicroTaskQueue (zone.js:602)
at <anonymous>
The error might be caused by the fact that every time FirebaseUIModule
is imported then also firebaseui.service
is loaded.
-
When a module is loaded normally it is registered in the root app injector and a service that module is also loading is injected. Now Angular can find the given service in the app root injector and provides a singleton for the whole app. No new service provider instances are created.
-
When a module is lazy-loaded a child injector is created and the given service is registered with that child injector. Now, when lazy component is created it must inject the given service. The given service provider is in child injector of that lazily-loaded module. So a new instance of the service is created. This happens for each lazily-loaded module. Here it causes to create multiple AuthUI instances.
Full explanation is given here - https://angular.io/guide/ngmodule-faq#q-why-bad
The solution might be to want from developer to import firebaseui.service
in the app.module
and put it in providers
so the service is available globally and not load firebaseui.service
in firebaseui.module
?
Issue Analytics
- State:
- Created 6 years ago
- Comments:8 (5 by maintainers)
Top GitHub Comments
Thank you. I’m not sure whether I’ll have time today to try it. I’ll inform you soon though.
Ok, I found a fix. Version 0.4.4 is live now. Please give it a try and tell me if it solved the issue.