isAuthenticated$ return false

We have Angular App which we wrapper in Ionic. In guard class we check if user is authenticated by checking isAutheticated$. Eventhough the user just authenticated the isAuthenticated returns false. Next time it returns true and stays like that. We’ve pretty much followed the example from auth0 site, except there is no guard class there.
We have custom domain on production instance configured and we use refresh tokens and we really run out of ideas :frowning:

this is my auth guard class

export class AuthGuard implements CanActivate {

  constructor(private auth: AuthService, private router: Router, private configService: ConfigService) { }

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.auth.isAuthenticated$.pipe(
      tap(loggedIn => {
        console.log("isAuthenticated$",loggedIn)
        
        if (!loggedIn) {
          this.login();
        } 
      })
    );
  }

  private login() {
    this.auth
      .loginWithRedirect({
        async openUrl(url: string) {
          await Browser.open({ url, windowName: '_self' })
        }
      })
      .subscribe(
        {
          error: err => console.error('Error triggering login', err)
        }
      );
  }

}

this is how we listen for authentication browser events in the main app component

    async initAuth0Listener() {
        App.addListener('appUrlOpen', ({url}) => {
            // Must run inside an NgZone for Angular to pick up the changes
            // https://capacitorjs.com/docs/guides/angular
            this.ngZone.run(() => {
                if (url?.startsWith(callbackUri)) {  // || url?.includes('taalhammer.eu.auth0.com')
                    console.debug('callbackUri '+ callbackUri);
                    console.debug('url '+ url);
                    if (url.includes('state=') && (url.includes('error=') || url.includes('code='))) {
                        this.auth.handleRedirectCallback(url).pipe(
                            mergeMap(() => {
                                console.debug('inside handle redirect callback');
                                this.router.navigateByUrl('/learning', {replaceUrl: true});
                                return Browser.close();
                            }
                        )).subscribe();
                    } else if (url.includes('callback')) {
                        this.router.navigateByUrl('/callback', {replaceUrl: true})
                        Browser.close();
                    } else {
                        Browser.close();
                    }
                }
            });
        });
    }

and this is Auth0 client config

onst config: AuthConfig = {
    domain,
    clientId,
    authorizationParams: {
        redirect_uri: 'com.taalhammer.app://th-dev.eu.auth0.com/capacitor/com.taalhammer.app/callback',
        audience: environment.auth.audience
    },
    // For using Auth0-Angular with Ionic on Android and iOS,
    // it's important to use refresh tokens without the fallback
    useRefreshTokens: true,
    useRefreshTokensFallback: false,
    cacheLocation: 'localstorage',            
    // The AuthHttpInterceptor configuration https://auth0.com/docs/libraries/auth0-angular-spa#configure-the-http-interceptor
    httpInterceptor: {
        allowedList: [ 
            `${environment.auth.audience}*`,
            {
                uri: `https://${ environment.auth.domain }/api/v2/users/`,
                tokenOptions: {
                  authorizationParams: {
                    audience: `https://${ environment.auth.domain }/api/v2/`,
                    scope: 'read:users',
                  }
                },
              },
    ]}

};

here’s the screencast with the strange isAuthenticated$ behaviour

Hey there @lukaszkorona !

Please check this capacitorjs’ doc out - Storage | Capacitor Documentation to reference the local storage setting and its alternatives.

Particularly this statement may be somehow explanatory:

Local Storage can be used for small amounts of temporary data, such as a user id, but must be considered transient , meaning your app needs to expect that the data will be lost eventually.

An assumption could be that the app is able to successfully reach the local storage for an existing refresh token (to exchange it for a new access token) on a “best effort” basis.

Sorry I don’t understand what you mean. Seems the local storage is a good option for refresh token. Do you think diffrently?

I also don’t understand how could we use those other option you mentioned. We simply configure auth0 client with checkLocation parameter. What else we could do here to use the refresh tokens?

I am facing the same issue in my Ionic app.
It almost seems like isAuthenticated takes a while to be set to true after authentication.

This one seems to be related: Ionic 2 - Login success (according to logs) but isAuthenticated() is false (IOS 11.2)