0

I am working on Firebase authentication with angular 4. I am trying to display the error messages but it is showing on the second click. In the console, it shows the error on the first click, but when I bind it to HTML component it shows the click on the second click. I am using the following auth service.

import { Injectable } from '@angular/core';
import { AngularFireDatabaseModule, AngularFireDatabase } from 'angularfire2/database';
import { AngularFireAuth } from 'angularfire2/auth';
import { Router } from "@angular/router";
import * as firebase from 'firebase';

@Injectable()
export class AuthService {

  authState: any = null;
  isLoggedIn: any;
  error: any;

  constructor(private afAuth: AngularFireAuth,
              private db: AngularFireDatabase,
              private router:Router) {

            this.afAuth.authState.subscribe((auth) => {
              this.authState = auth
            });
          }

  // Returns true if user is logged in
  get authenticated(): boolean {
    return this.authState !== null;
  }

  // Returns current user data
  get currentUser(): any {
    return this.authenticated ? this.authState : null;
  }

  // Returns
  get currentUserObservable(): any {
    return this.afAuth.authState
  }

  // Returns current user UID
  get currentUserId(): string {
    return this.authenticated ? this.authState.uid : '';
  }
  emailLogin(email:string, password:string) {
     return this.afAuth.auth.signInWithEmailAndPassword(email, password)
       .then((user) => {
         this.router.navigate(['/dashboard_home'])
         this.isLoggedIn = this.authenticated;
       })
       .catch(error => {
        this.error = error;
        console.log(error)
      });
  }

  // Sends email allowing user to reset password
  resetPassword(email: string) {
    var auth = firebase.auth();

    return auth.sendPasswordResetEmail(email)
      .then(() => console.log("email sent"))
      .catch((error) => console.log(error))
  }


  //// Sign Out ////
  signOut(): void {
    this.afAuth.auth.signOut();
    this.router.navigate(['/administrator'])
  }

  //// Helpers ////
  private updateUserData(): void {
  // Writes user name and email to realtime db
  // useful if your app displays information about users or for admin features
    let path = `users/${this.currentUserId}`; // Endpoint on firebase
    let data = {
                  email: this.authState.email,
                  name: this.authState.displayName
                }

    this.db.object(path).update(data)
    .catch(error => console.log(error));

  }
}

My login.html page looks like that.

<div class="card-block">
   <div class="alert alert-danger" role="alert" *ngIf="error">{{ error }}</div>
   <form autocomplete="off" id="loginAdmin" (submit)="loginAdmin($event)">
      <div class="row">
         <div class="col-md-4 mx-auto">
            <mat-form-field>
               <input type="text" id="username" name="username" matInput placeholder="Användarnamn">
            </mat-form-field>
         </div>
      </div>
      <div class="row">
         <div class="col-md-4 mx-auto">
            <mat-form-field>
               <input type="password" id="password" name="password" matInput placeholder="Lösenord">
            </mat-form-field>
         </div>
      </div>
      <div class="row"></div>
      <div class="row">
         <div class="col-md-12 text-center">
            <button type="submit" mat-raised-button>Logga in</button>
         </div>
      </div>
   </form>
</div>

and my component.ts for login page is given

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../services/auth/auth.service';
import {Router} from "@angular/router";
@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
  error = '';

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

  loginAdmin(e) {
    e.preventDefault();
    var email = e.target.elements[0].value;
    var password = e.target.elements[1].value;
    if(email && password) {
      var responses = this.authService.emailLogin(email, password);
      this.error = this.authService.error;
    }

  }
}

If you use the above service you can login use. but it shows errors in the console if email and password are not correct, and it is not showing on binding with HTML. The binding look like that.

<div class="alert alert-danger" role="alert" *ngIf="error">{{ error }}</div>

Now What I want, to send display error on first click as well as to get all the user data logged in.

1 Answer 1

1

I fond the solution. This service work for me.

import {AngularFireAuth} from 'angularfire2/auth';

@Injectable()
export class AuthService {

  authState: any = null;

  constructor(private afAuth: AngularFireAuth, private router: Router) {
    this.afAuth.authState.subscribe((auth) => {
      this.authState = auth
    });
  }

  get isUserAnonymousLoggedIn(): boolean {
    return (this.authState !== null) ? this.authState.isAnonymous : false
  }

  get currentUserId(): string {
    return (this.authState !== null) ? this.authState.uid : ''
  }

  get currentUserName(): string {
    return this.authState['email']
  }

  get currentUser(): any {
    return (this.authState !== null) ? this.authState : null;
  }

  get isUserEmailLoggedIn(): boolean {
    if ((this.authState !== null) && (!this.isUserAnonymousLoggedIn)) {
      return true
    } else {
      return false
    }
  }

  signUpWithEmail(email: string, password: string) {
    return this.afAuth.auth.createUserWithEmailAndPassword(email, password)
      .then((user) => {
        this.authState = user
      })
      .catch(error => {
        console.log(error)
        throw error
      });
  }

  loginWithEmail(email: string, password: string) {
    return this.afAuth.auth.signInWithEmailAndPassword(email, password)
      .then((user) => {
        this.authState = user
      })
      .catch(error => {
        console.log(error)
        throw error
      });
  }

  signOut(): void {
    this.afAuth.auth.signOut();
    this.router.navigate(['/'])
  }
}

For more detail visit Angular 4 Firebase Auth – Email/Password Authentication with AngularFire2 v4

Sign up to request clarification or add additional context in comments.

4 Comments

Hiya How did you change your component and view to actually display the error that you throw in your AuthService?
This was the issue that I faced almost three days. Follow this link which helped me to fix that. javasampleapproach.com/frontend/angular/…
past this in your view ... <p *ngIf="errorMessage.length > 0" class="alert alert-danger"> {{errorMessage}} </p> <p *ngIf="error.message.length > 0" class="alert alert-danger"> {{error.message}} </p>
To check if user is login or not <div *ngIf="authService.currentUser"></div>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.