7
votes

I'm trying to integrate firebase via AngularFire2 with Nebular.

I am initializing AngularFire2 in my app module and when I check it seems like the firebase app is getting configured, but for some reason the auth module is not attached or something like that because firebase.auth() is null and should be a function.

Debug output

It seems as if firebase is getting initialized.

https://user-images.githubusercontent.com/60548/35354017-c198eee2-00fd-11e8-8030-95654ebb2d5f.png screenshot 2018-01-24 11 51 16

But then it throws a TypeError. https://user-images.githubusercontent.com/60548/35353848-50c7e506-00fd-11e8-9563-b29efef69e2c.png screenshot 2018-01-24 11 51 27

core.module.ts

const NB_CORE_PROVIDERS = [
  ...DataModule.forRoot().providers,
  ...NbAuthModule.forRoot({
    providers: {
      email: {
        service: NbFirebaseAuthProvider,
        config: {
        },
      },
    },
  }).providers,
  AnalyticsService,
  NbFirebaseAuthProvider,
];

@NgModule({
  imports: [
    CommonModule,
  ],
  exports: [
    NbAuthModule,
  ],
  declarations: [],
})
export class CoreModule {
  constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
    throwIfAlreadyLoaded(parentModule, 'CoreModule');
  }

  static forRoot(): ModuleWithProviders {
    return <ModuleWithProviders>{
      ngModule: CoreModule,
      providers: [
        ...NB_CORE_PROVIDERS,
      ],
    };
  }
}

app.module.ts

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    HttpModule,
    AngularFireModule.initializeApp({
      apiKey: "<removed>",
      authDomain: "<removed>",
      databaseURL: "<removed>",
      projectId: "<removed>",
      storageBucket: "<removed>",
      messagingSenderId: "65580220719"
    }),
    AngularFireAuthModule,
    AppRoutingModule,
    NgbModule.forRoot(),
    ThemeModule.forRoot(),
    CoreModule.forRoot(),
  ],
  bootstrap: [AppComponent],
  providers: [
    { provide: APP_BASE_HREF, useValue: '/' },
  ],
})
export class AppModule {
}

firebase-auth.provider.ts

@Injectable()
export class NbFirebaseAuthProvider extends NbAbstractAuthProvider {
  constructor(
    private afa : AngularFireAuth
  ) {
    super();
    console.log(this.afa);
  }

  protected defaultConfig: NgEmailPassAuthProviderConfig = {
    login: {
      redirect: {
        success: '/',
        failure: null,
      },
    },
    register: {
      redirect: {
        success: '/',
        failure: null,
      },
    },
    requestPass: {
      redirect: {
        success: '/auth/login',
        failure: null,
      },
    },
    resetPass: {
      redirect: {
        success: '/auth/login',
        failure: '/auth/reset-password',
      },
    },
    logout: {
      redirect: {
        success: '/auth/login',
        failure: null,
      },
    },
  };


  /**
   * Firebase authentication.
   *
   * @param data any
   * @returns Observable<NbAuthResult>
   */
  authenticate(data?: any): Observable<NbAuthResult> {
    console.log(this.afa);
    return Observable.fromPromise(this.afa.auth.signInWithEmailAndPassword(data.email, data.password))
      .map((res) => {
        return this.processSuccess(res, this.getConfigValue('login.redirect.success'), [res.message]);
      })
      .catch((res) => {
        return Observable.of(
          this.processFailure(res, this.getConfigValue('login.redirect.failure'), [res.message]),
        );
      });
  }

  /**
   * Firebase registration.
   *
   * @param data any
   * @returns Observable<NbAuthResult>
   */
  register(data?: any): Observable<any> {
    return Observable.fromPromise(this.afa.auth.createUserWithEmailAndPassword(data.email, data.password))
      .map((res) => {
        return Observable.fromPromise(this.afa.auth.currentUser.updateProfile({
          displayName: data.fullName,
          photoURL: '',
        })).map((update) => {
          return this.processSuccess(res, this.getConfigValue('register.redirect.success'), [res.message]);
        });
      })
      .catch((res) => {
        return Observable.of(
          this.processFailure(res, this.getConfigValue('register.redirect.failure'), [res.message]),
        );
      });
  }

  /**
   * Firebase restore password.
   *
   * @param data any
   * @returns Observable<NbAuthResult>
   */
  requestPassword(data?: any): Observable<NbAuthResult> {
    return Observable.fromPromise(this.afa.auth.sendPasswordResetEmail(data.email))
      .map((res) => {
        return this.processSuccess(res, this.getConfigValue('requestPass.redirect.success'), []);
      })
      .catch((res) => {
        return Observable.of(this.processFailure(res,  this.getConfigValue('requestPass.redirect.failure'),
          [res.message]));
      });
  }

  /**
   * Firebase reset password.
   *
   * @param data any
   * @returns Observable<NbAuthResult>
   */
  resetPassword(data?: any): Observable<NbAuthResult> {
    if (this.afa.auth.currentUser) {
      return Observable.fromPromise(this.afa.auth.currentUser.updatePassword(data.password))
        .map((res) => {
          return this.processSuccess(res, this.getConfigValue('resetPass.redirect.success'), []);
        })
        .catch((res) => {
          return Observable.of(this.processFailure(res,  this.getConfigValue('resetPass.redirect.failure'),
            [res.message]));
        });
    }

    return Observable.of(this.processFailure([],  this.getConfigValue('resetPass.redirect.failure'),
      ['Please, sign in to be able to reset your password']));
  }

  /**
   * Firebase logout.
   *
   * @param data any
   * @returns Observable<NbAuthResult>
   */
  logout(data?: any): Observable<NbAuthResult> {
    return Observable.fromPromise(this.afa.auth.signOut())
      .map((res) => {
        return this.processSuccess(res, this.getConfigValue('logout.redirect.success'),  []);
      })
      .catch((res) => {
        return Observable.of(this.processFailure(res, this.getConfigValue('logout.redirect.failure'),
          [res.message]));
      });
  }

  private processSuccess(response?: any, redirect?: any, messages?: any): NbAuthResult {
    return new NbAuthResult(true, response, redirect, [], messages);
  }

  private processFailure(response?: any, redirect?: any, errors?: any): NbAuthResult {
    return new NbAuthResult(false, response, redirect, errors, []);
  }
}
1
The text in those images is very small and difficult to read. Instead of posting images, it's strong encouraged that you simply copy code and error message into the text of your question. They're easier to read and search that way. - Doug Stevenson
@DougStevenson yeah, I see that now. It's unfortunate SO doesn't link to the images themselves as they are full-size screenshots and are not difficult to read. - user79854
Remove the CoreModule and relocate the modules. Consider making CoreModule a pure services module with no declarations. - botika
Could you possibly upload your project to GitHub or something similar? - Drei
@lolsborn Did you get this fixed? - Sithu

1 Answers

0
votes

It's because the app instance you are parsing to AngularFireAuth doesn't have the auth method attached to it yet. You need import { AngularFireAuth } from 'angularfire2/auth'; in firebase-auth.provider.ts.

I'd suggest using codesandbox to make sure we are seeing the same code you are working with.

*Edit: if you are using the new api, you can do import * as firebase from 'firebase/app'; and then call firebase.auth()