Firebase authentication in Ionic application Cannot read property 'emailVerified' of null TypeError

I’m trying to use Firebase authentication in Ionic TypeScript application

Here is signIn(), checks if email verified with condition if (this.authService.userEmailVerified):

async signIn() {
    const loading = await this.loadingController.create();
    await loading.present();
    this.authService.signIn(this.credentialForm.value).then(
      (res) => {
        loading.dismiss();
        if (this.authService.userEmailVerified) {
          this.router.navigateByUrl(
            '/home/' + this.credentialForm.value.email,
            {
              replaceUrl: true,
            }
          );
        } else {
          window.alert('Email is not verified');
          return false;
        }
      },
      async (err) => {
        loading.dismiss();
        const alert = await this.alertController.create({
          header: 'Error',
          message: err.message,
          buttons: ['OK'],
        });
        await alert.present();
      }
    );
  }

requesting public authService: AuthenticationService load import { AuthenticationService } from '../shared/auth.service'; in auth.service.ts:

  get userEmailVerified(): boolean {
    const user = JSON.parse(localStorage.getItem('user'));
    return user.emailVerified !== false ? true : false;
  }

Email is verified, and now with browser load, I’m trying to signIn(), but Chrome console shows error:

ERROR Error: Uncaught (in promise): TypeError: Cannot
read property ‘emailVerified’ of null TypeError: Cannot read property
‘emailVerified’ of null
at AuthenticationService.get userEmailVerified [as userEmailVerified]

with second attempt signIn() is successful and this.authService.userEmailVerified value is true.

Then signOut() and again signIn() and same way error appears, seems like uncatchable with if (this.authService.userEmailVerified == null) or === null before if (this.authService.userEmailVerified), with return user.emailVerified !== false ? true : false; from auth.service.ts, and then again error just disappears with second click attempt, successfully signIn().

login.page.ts signUp():

async signUp() {
    const loading = await this.loadingController.create();
    await loading.present();
    this.authService.signUp(this.credentialForm.value).then(
      (user) => {
        loading.dismiss();
        this.authService.SendVerificationMail();
        this.router.navigate(['verify-email']);
      },
      async (err) => {
        loading.dismiss();
        const alert = await this.alertController.create({
          header: 'Sign up failed',
          message: err.message,
          buttons: ['OK'],
        });
        await alert.present();
      }
    );
  }

and auth.service.ts :

export class AuthenticationService {
  userData: any;
  constructor(
    public afStore: AngularFirestore,
    public ngFireAuth: AngularFireAuth,
    public router: Router,
    public ngZone: NgZone 
  ) {

    this.ngFireAuth.authState.subscribe((user) => {
      if (user) {
        this.userData = user;
        localStorage.setItem('user', JSON.stringify(this.userData));
        JSON.parse(localStorage.getItem('user'));
      } else {
        localStorage.setItem('user', null);
        JSON.parse(localStorage.getItem('user'));
      }
    });
  }

  get userEmailVerified(): boolean {
    const user = JSON.parse(localStorage.getItem('user'));
    return user.emailVerified !== false ? true : false;
  }

  SignOut(): Promise<void> {
    return this.ngFireAuth.signOut().then(() => {
      localStorage.removeItem('user');
      this.router.navigate(['login']);
    });
  }

  async signUp({ email, password }) {
    const credential = await this.ngFireAuth.createUserWithEmailAndPassword(
      email,
      password
    );
    const uid = credential.user.uid;
    return this.afStore
      .doc('users/${uid}')
      .set({ uid, email: credential.user.email });
  }

  async signIn({ email, password }) {
    return this.ngFireAuth.signInWithEmailAndPassword(email, password);
  }
}

Advice would be helpful

Lots of stuff going on I am not sure about…

How is the signup method defined (signIn)? You are doing nothing with the res from the signin?

In general, if you see a second login work well where as a first won’t, then you basically have an inconsistency in your code vs what is really happening. Likely the second login is working because it is taking the authentication result of the first one. Likely you are not waiting correctly for the result.

this.authService.userEmailVerified is an interesting method. Apparently if localstorage holds a undefined/null value you consider that a true verification? Besides the interesting part that it seems to pass on a null value?

Next, you may refrain from using localStorage, but use Ionic Storage going forward, even though for now it may suffice.

And I suspect you do component communication via localStorage.

So lots of things going on. Also what the isn’t shown (yet)

Hello, Tommertom!

Thank you for your feedback and sorry for the late replay

I’ve edited the question with auth.service.ts code

and I’ve found the solution, which works fine for me, solves actual issue with var isVerified = user.emailVerified; and if (isVerified) instead this.authService.userEmailVerified with get userEmailVerified(): boolean:

this.ngFireAuth.authState.subscribe(async (user) => {
  if (user) {
     var isVerified = user.emailVerified;
     if (isVerified) {
        console.log('Email is verified');
     } else {
        console.log('Email is not verified');           
     }
   }
});