[Fixed] Angular/fire authState.subscribe not respond to logout

Issue

I’m new to angular and I’m trying to authenticate with firebase. I already build the login/register and logout. It work fine now, but now I want to display a navbar(completely separate component) which has a login button and logout button. I need to toggle these buttons according to the user’s authState. So I used subscribe on authState. But it only works when the user logging in. It does not trigger when the user logout. It is supposed to return null when a user logout right? I checked the authState inside the authService, it’s null after the user logged out. So what am I doing wrong here?

Here is my code.

auth.service.ts

import { Injectable } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { AngularFireAuth } from '@angular/fire/auth';
import { Observable, of } from 'rxjs';
import * as firebase from 'firebase/app';

@Injectable({
  providedIn: 'root'
})

export class AuthService {
  authState: any;

  constructor(
    public db: AngularFirestore,
    public mAuth: AngularFireAuth
  ) {}

  getAuthState() {
    return this.mAuth.authState;
  }
  doLogout() {
    return new Promise((resolve, reject) => {
      if (firebase.auth().currentUser) {
        this.mAuth.auth.signOut();
        resolve();
      } else {
        reject();
      }
    });
  }

/* login, register, etc... */

}

nav.component.ts

import { Component, OnInit } from '@angular/core';
import { AuthService } from 'src/app/auth/auth.service';
import { Router } from '@angular/router';
import * as firebase from 'firebase/app';

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.scss']
})
export class NavbarComponent implements OnInit {

  user: any;

  constructor(
    private authService: AuthService,
    private router: Router) {}

  ngOnInit() {
    this.authService.getAuthState().subscribe( user => {
      /* this doesn't respond to logout ... */
      console.log(user);
      this.user = user;
    });
  }
  tryLogout() {
    this.authService.doLogout()
      .then(res => {
        console.log('tryLogout', res);
        this.router.navigate(['/login']);
      }, err => console.log(err));
  }
}

Solution

I’m pretty sure that your authService doLogout() is returning a promise of a promise.

auth.signout() already returns a promise.

I think that your doLogout() function should just be:

return this.mAuth.auth.signout()

Sidenote : I ran into this exact same problem, and it was because authstate is somehow affected by router.navigate. My mistake was:

this.authstate.signout();
this.router.navigate(['/']);

But with the above code, the authstate would never actually change. What fixed the problem was:

this.authstate.signout().then(this.router.navigate(['/'])

Leave a Reply

(*) Required, Your email will not be published