Angular Firebase Auth - Email/Password Authentication with AngularFire2 v4
angular
65
firebase
35
authentication
20
Male avatar

loveprogramming viết ngày 25/03/2021

https://grokonez.com/frontend/angular/angular-4-firebase-auth-email-password-authentication-with-angularfire2-email-login

Angular Firebase Auth - Email/Password Authentication with AngularFire2 v4

In this tutorial, we're gonna look at way to implement Email/Password authentication (with form validation) using AngularFire2 v4.

Related Posts:

I. Technology

  • Angular
  • AngularFire2 4.0

    II. Overview

    We will build an Angular App that allows user sign up and login (with form validation): angular-4-firebase-auth-email-password-overview

    II. How to do

    1. Set up the Firebase Project & Install AngularFire2

    Please visit this post to know step by step.

angular-4-firebase-integration-copy-firebase-project-config

2. Enable Firebase Auth for Email/Password

Go to your Project on Firebase Console -> Authentication tab -> SIGN-IN METHOD -> enable Email/Password:
angular-4-firebase-auth-email-password-enable-console

3. Auth Service


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(['/'])
  }
}
  • We subscribe to the AngularFire auth observable that returns a FirebaseAuthState object. This object is null when logging out, and contains useful User Information (UID, Display Name, Photo URL...) when logging in.
  • We use:
  • AngularFireAuth.auth.createUserWithEmailAndPassword() to sign up new account.
  • AngularFireAuth.auth.signInWithEmailAndPassword() to log in.
  • AngularFireAuth.auth.signOut() to log out.
  • We also catch Exception to get Error information and throw it for register/login validation (Error will be catch later at Component which uses this service's functions)

    4. App Module

    
    // ...
    import {NgModule} from '@angular/core';
    import {FormsModule} from '@angular/forms';

import {AngularFireModule} from 'angularfire2';
import {AngularFireAuthModule} from 'angularfire2/auth';

import {AuthService} from './auth/auth.service';

@NgModule({
// ...
imports: [
BrowserModule,
FormsModule,
AngularFireModule.initializeApp(environment.firebase),
AngularFireAuthModule
],
providers: [AuthService],
// ...
})

5. Use Service - Login Component


import {Component, OnInit} from '@angular/core';
import {Router} from '@angular/router';
import {AuthService} from '../auth.service';

@Component({
  selector: 'user-login',
  templateUrl: './user-login.component.html',
  styleUrls: ['./user-login.component.css']
})
export class UserLoginComponent implements OnInit {

  email = '';
  password = '';
  errorMessage = '';
  error: {name: string, message: string} = {name: '', message: ''};

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

  ngOnInit() {
  }

  onSignUp(): void {
    if (this.validateForm(this.email, this.password)) {
      this.authService.signUpWithEmail(this.email, this.password)
        .then(() => {
          this.router.navigate(['/user'])
        }).catch(_error => {
          this.error = _error
          this.router.navigate(['/'])
        })
    }
  }

  onLoginEmail(): void {
    if (this.validateForm(this.email, this.password)) {
      this.authService.loginWithEmail(this.email, this.password)
        .then(() => this.router.navigate(['/user']))
        .catch(_error => {
          this.error = _error
          this.router.navigate(['/'])
        })
    }
  }

  validateForm(email: string, password: string): boolean {
    // validate this.errorMessage
  }
}

We will validate 2 times:

  • before calling AuthService using validateForm()
  • after AuthService throws an error using firebase.Thenable.catch()

Template:

<p *ngIf="errorMessage.length > 0" class="text-danger">
    {{errorMessage}}</p>

<p *ngIf="error.message.length > 0" class="text-danger">
    {{error.message}}</p>

<form (ngSubmit)="onSignUp()">
    <div class="form-group">
        <label for="email">Email</label> <input type="email"
            class="form-control" id="email" name="email" required
            [(ngModel)]="email">
    </div>

    <div class="form-group">
        <label for="password">Password</label> <input type="password"
            class="form-control" id="password" name="password" required
            [(ngModel)]="password">
    </div>

    <button type="submit" class="btn btn-success">Register/Login</button>
</form>

III. Practice

1. Project structure

angular-4-firebase-auth-anonymous-structure

angular-4-firebase-auth-email-password-overview-component

2. App Module

import {environment} from '../environments/environment';
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {AppRoutingModule} from './app-routing.module';

import {AngularFireModule} from 'angularfire2';
import {AngularFireAuthModule} from 'angularfire2/auth';

import {AuthService} from './auth/auth.service';

import {AppComponent} from './app.component';
import {UserLoginComponent} from './auth/user-login/user-login.component';
import {UserInfoComponent} from './auth/user-info/user-info.component';

@NgModule({
  declarations: [
    AppComponent,
    UserLoginComponent,
    UserInfoComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    AppRoutingModule,
    AngularFireModule.initializeApp(environment.firebase),
    AngularFireAuthModule
  ],
  providers: [AuthService],
  bootstrap: [AppComponent]
})
export class AppModule {}

3. Auth Service


import {Injectable} from '@angular/core';
import {Router} from '@angular/router';
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(['/'])
  }
}

4. Components

4.1 User Login Component

user-login.component.ts


import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from '../auth.service';

@Component({
  selector: 'user-login',
  templateUrl: './user-login.component.html',
  styleUrls: ['./user-login.component.css']
})
export class UserLoginComponent implements OnInit {

  isNewUser = true;
  email = '';
  password = '';
  errorMessage = '';
  error: { name: string, message: string } = { name: '', message: '' };

  resetPassword = false;

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

  ngOnInit() { }

  checkUserInfo() {
    if (this.authService.isUserEmailLoggedIn) {
      this.router.navigate(['/user'])
    }
  }

  clearErrorMessage() {
    this.errorMessage = '';
    this.error = { name: '', message: '' };
  }

  changeForm() {
    this.isNewUser = !this.isNewUser
  }

  onSignUp(): void {
    this.clearErrorMessage()

    if (this.validateForm(this.email, this.password)) {
      this.authService.signUpWithEmail(this.email, this.password)
        .then(() => {
          this.router.navigate(['/user'])
        }).catch(_error => {
          this.error = _error
          this.router.navigate(['/'])
        })
    }
  }

  onLoginEmail(): void {
    this.clearErrorMessage()

    if (this.validateForm(this.email, this.password)) {
      this.authService.loginWithEmail(this.email, this.password)
        .then(() => this.router.navigate(['/user']))
        .catch(_error => {
          this.error = _error
          this.router.navigate(['/'])
        })
    }
  }

  validateForm(email: string, password: string): boolean {
    if (email.length === 0) {
      this.errorMessage = 'Please enter Email!'
      return false
    }

    if (password.length === 0) {
      this.errorMessage = 'Please enter Password!'
      return false
    }

    if (password.length  this.resetPassword = true)
      .catch(_error => {
        this.error = _error
      })
  }
}

user-login.component.html

{{checkUserInfo()}}
<div *ngIf="!authService.isUserEmailLoggedIn">
    <div style="width: 350px;" *ngIf="isNewUser">

        <p *ngIf="errorMessage.length > 0" class="text-danger">
            {{errorMessage}}</p>

        <p *ngIf="error.message.length > 0" class="text-danger">
            {{error.message}}</p>

        <form (ngSubmit)="onSignUp()">
            <div class="form-group">
                <label for="email">Email</label>
                <input type="email" class="form-control" id="email" name="email" required [(ngModel)]="email">
            </div>

            <div class="form-group">
                <label for="password">Password</label>
                <input type="password" class="form-control" id="password" name="password" required [(ngModel)]="password">
            </div>

            <button type="submit" class="btn btn-success">Register</button>
        </form>

        <h4 class="text-primary" (click)="changeForm()">Already have an Account? >> Log In</h4>
    </div>

    <div style="width: 350px;" *ngIf="!isNewUser">

        <p *ngIf="errorMessage.length > 0" class="text-danger">
            {{errorMessage}}</p>

        <p *ngIf="error.message.length > 0" class="text-danger">
            {{error.message}}</p>

        <form (ngSubmit)="onLoginEmail()">
            <div class="form-group">
                <label for="email">Email</label>
                <input type="text" class="form-control" id="email" name="email" required [(ngModel)]="email">
            </div>

            <div class="form-group">
                <label for="password">Password</label>
                <input type="password" class="form-control" id="password" name="password" required [(ngModel)]="password">
            </div>

            <button type="submit" class="btn btn-success">Log In</button>
        </form>

        <h4 class="text-primary" (click)="changeForm()">Not have any Account yet? >> Register</h4>

        <a *ngIf="!resetPassword && isValidMailFormat(email)" class="text-danger" (click)="sendResetEmail()">Reset Password for {{email}}</a>
        <p *ngIf="resetPassword" class="text-success">Check your email to reset password!</p>

    </div>
</div>

4.2 User Info Component

user-info.component.ts


import {Component, OnInit} from '@angular/core';
import {AuthService} from '../auth.service';

@Component({
  selector: 'user-info',
  templateUrl: './user-info.component.html',
  styleUrls: ['./user-info.component.css']
})
export class UserInfoComponent implements OnInit {

  constructor(public authService: AuthService) {}

  ngOnInit() {
  }

  logout() {
    this.authService.signOut();
  }

}

user-info.component.html

<div *ngIf="authService.currentUser">
    <h5 class="text-primary">User Information</h5>
    <h4>
        <strong>UID:</strong> {{ authService.currentUserId }}
    </h4>
    <h4>
        <strong>Email:</strong> {{ authService.currentUserName }}
    </h4>
    <button class="button" (click)="logout()">Logout</button>
</div>

5. App Routing Module

app-routing.module.ts


import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';

import {UserLoginComponent} from './auth/user-login/user-login.component';
import {UserInfoComponent} from './auth/user-info/user-info.component';

const routes: Routes = [
  {path: '', redirectTo: 'login', pathMatch: 'full'},
  {path: 'login', component: UserLoginComponent},
  {path: 'user', component: UserInfoComponent},
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})

export class AppRoutingModule {}

6. App Component

app.component.ts


import {Component} from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'JavaSampleApproach';
  description = 'Angular4-Firebase Demo';
}

app.component.html

<div class="container">
    <div style="color: blue; margin-bottom:20px">
        <h1>{{title}}</h1>
        <h3>{{description}}</h3>
    </div>

    <router-outlet></router-outlet>
</div>

7. Check Result

Run the App, go to http://localhost:4200/.

Register and Login:
angular-4-firebase-auth-email-password-login-result

Firebase Console:
angular-4-firebase-auth-email-password-console-result

Check Validation:
angular-4-firebase-auth-email-password-validation-result

IV. Source Code

Angular4Firebase-Auth-Email-Password

https://grokonez.com/frontend/angular/angular-4-firebase-auth-email-password-authentication-with-angularfire2-email-login

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

Male avatar

loveprogramming

451 bài viết.
79 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
Male avatar
1 0
Tutorial Link: (Link) (Ảnh) Django is a Pythonbased free and opensource web framework that follows the modeltemplateview architectural pattern. A...
loveprogramming viết 6 tháng trước
1 0
Male avatar
1 0
https://loizenai.com/angular11nodejspostgresqlcrudexample/ Angular 11 Node.js PostgreSQL Crud Example (Ảnh) Tutorial: “Angular 11 Node.js Postg...
loveprogramming viết 5 tháng trước
1 0
Male avatar
1 0
Angular Spring Boot jwt Authentication Example Github https://loizenai.com/angularspringbootjwt/ (Ảnh) Tutorial: ” Angular Spring Boot jwt Authe...
loveprogramming viết 5 tháng trước
1 0
Bài viết liên quan
White
26 11
Quá trình lột xác ngoạn mục của một hệ thống cổ lỗ sĩ khi được thiết kế cẩn thận: 1 usecase thành công của việc áp dụng triệt để các phương pháp xử...
Minh Monmen viết 11 tháng trước
26 11
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


Male avatar
{{userFollowed ? 'Following' : 'Follow'}}
451 bài viết.
79 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!