Skip to content

currentUser | async never resolves, browser hangs #2378

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

Closed
pgg opened this issue Apr 2, 2020 · 4 comments
Closed

currentUser | async never resolves, browser hangs #2378

pgg opened this issue Apr 2, 2020 · 4 comments

Comments

@pgg
Copy link

pgg commented Apr 2, 2020

Version info

Angular:
9.1.0
Firebase:
7.13.1
AngularFire:
6.0.0
Other (e.g. Ionic/Cordova, Node, browser, operating system):
chrome 80.0.3987.162, macOS Catalina 10.15.3

How to reproduce these conditions

in component html {{auth.currentUser | async}}

Failing test unit, Plunkr, or JSFiddle demonstrating the problem

Steps to set up and reproduce

Sample data and security rules

<-- include/attach/link to some json sample data (or provide credentials to a sanitized, test Firebase project) -->

Debug output

** Errors in the JavaScript console **

** Output from firebase.database().enableLogging(true); **

** Screenshots **

Expected behavior

Actual behavior

@jamesdaniels
Copy link
Member

Thanks for the report, will look into this.

@curiouscod3
Copy link

curiouscod3 commented Apr 3, 2020

currentUser returns null.

getCurrentUser$() {
    return this.afAuth.currentUser;
  }
//  in auth.guard.ts
this.authFireSV.getCurrentUser$().then(
        u => {
          console.log(' --> currentUser$', u);  <--- null 
        }
 )

On the other hand,

this.afAuth.authState.pipe() method works!

authedUser() {
    return this.afAuth.authState.pipe(first());
  }
Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.900.7
@angular-devkit/build-angular     0.901.0
@angular-devkit/build-optimizer   0.901.0
@angular-devkit/build-webpack     0.901.0
@angular-devkit/core              9.1.0
@angular-devkit/schematics        9.1.0
@angular/cdk                      9.2.0
@angular/fire                     6.0.0
@angular/flex-layout              9.0.0-beta.29
@angular/material                 9.2.0
@ngtools/webpack                  9.1.0
@schematics/angular               9.1.0
@schematics/update                0.901.0
rxjs                              6.5.4
typescript                        3.8.3
webpack                           4.42.0

I think something is odd .
I've changed some code like the following.
I can get the currentUser$ promise now.

canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> {

    return this.authFireSV.authedUser().pipe(
      take(1),
      map(u => {
        console.log(" authedUser: ", u);

        if (u) {
          this.authFireSV.getCurrentUser$().then(
            u => {
              console.log(' --> currentUser$', u);
            }
          );
          return true;
        } else {
          this.notiSV.warn('Please Do SignIn');
          this.router.navigate(['/user']);
          return false;
        }
      })
    );

  }

@luisfelipediaz
Copy link

luisfelipediaz commented Apr 7, 2020

Hi,

It is likely that in AUTH.TS at line 50 'shareReplay ({bufferSize: 1, refCount: false})' is allowing only one subscriber to exist

const auth = of(undefined).pipe(
      observeOn(schedulers.outsideAngular),
      switchMap(() => zone.runOutsideAngular(() => import('firebase/auth'))),
      map(() => ɵfirebaseAppFactory(options, zone, nameOrConfig)),
      map(app => app.auth()),
     // I don't understand why share replay just once time
      shareReplay({ bufferSize: 1, refCount: false }),
    );

Thanks.

@jamesdaniels
Copy link
Member

Sorry I misunderstood the issue when first looking at it. Our .user observable does seem to have a problem with Zone.js that I'm looking into.

auth.currentUser | async will not work, as currentUser is a promise. It will just lock up your application.

from(auth.currentUser) is also not likely what you want as currentUser also resolves with the current known state for Firebase auth, often this is null (at least at first). Using a listener or in the case of AngularFire one of our observables .user or .authState is the more correct solution. You can see similar discussions on StackOverflow here https://stackoverflow.com/questions/37883981/cant-get-currentuser-on-load It is a weird API...

.currentUser would be good for a form/button action or something like that, when you need the currently signed in user for an operation on Firestore/RTDB.

As for the shareReplay, that's a cache on the current authentication instance for the current injection tree. bufferSize: 1 says to only cache the last emission, refCount: false say don't throw away the cache if everyone unsubscribes. This only gets at the firebase auth instance and makes the "jQuery-style" Firebase API more friendly to RXJS developers.

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

No branches or pull requests

4 participants