angularfire: ApplicationRef.isStable never goes to "true" when an instance of AngularFireAuth is injected

When AngularFireAuth is injected anywhere on the page, the ApplicationRef.isStable never emits true. This causes problems with latest @angular/service-worker, which relies on ApplicationRef.isStable to install the worker. This probably also would cause server-side rendering to timeout, but I didn’t test this.

Version info

Angular: 5.0.0

Firebase: 4.6.2

AngularFire: 5.0.0-rc4

How to reproduce these conditions

Inject AngularFireAuth into a component and subscribe to the ApplicationRef.isStable observable:

import { Component, ApplicationRef, ChangeDetectorRef } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  constructor(appRef: ApplicationRef, af: AngularFireAuth) {    
    appRef.isStable.subscribe(s => {
      console.log(s); 
    });
  }
}

Here is a project that reproduces the problem: https://stackblitz.com/edit/angularfire2-appref-isstable

Expected behavior

The ApplicationRef.isStable observable should emit true shortly after application is loaded.

Actual behavior

The ApplicationRef.isStable observable emits only initial false value.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 16
  • Comments: 25 (10 by maintainers)

Commits related to this issue

Most upvoted comments

The same issue when I injects AngularFirestore. We cannot use an @angular/service-worker as it is not registered due to this issue.

Any updates on this issue?

Fixed in rc7

This issue should be reopened. Angular9 + AngularFire6 has same issue.

Just talking with myself here, I managed to work around it by having to override the AngularFireAuth like this:

{ provide: AngularFireAuth, useClass: AngularFireOwnAuth },

And have this:

@Injectable()
class AngularFireOwnAuth extends AngularFireAuth {
  readonly idToken: Observable<string | null>;

  constructor(
     @Inject(FirebaseOptionsToken) options: any,
     @Optional() @Inject(FirebaseNameOrConfigToken) nameOrConfig: string|any|undefined,
     @Inject(PLATFORM_ID) platformId: Object,
     zone: NgZone
  ) {
    super(options, nameOrConfig, platformId, zone);

    this.idToken = this.user.pipe(
      switchMap(async user =>
        user ? zone.run(async() => await zone.runOutsideAngular(() => user.getIdToken())) : null
      )
    );
  }
}

This will make sure the getIdToken is called outside the angular zone. If this is called inside the zone, it will trigger the long setTimeout and prevent angular from ever getting stable. At least not for 3300000ms 😃

Once patched I’ll cut a new RC.

I’m actually tackling right now. Thanks for the report!

After a little more digging I found that the problem is originating from the fireauth.AuthUser.prototype.initializeProactiveRefreshUtility_.

This is at least triggered on login with using just email and password, or by using the getIdToken() and setting forceRefresh to true.

For now the workaround is whenever you call these functions is to wrap it inside a ngZone.runOutsideAngular -> ngZone.run

angularfire2 cannot leave RC stage until this is fixed.

I am having the same issue when injecting AngularFirestore