Angular Firebase Auth - Email/Password Authentication with AngularFire2 v4
angular
64
firebase
33
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

447 bài viết.
78 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
White
14 6
Firebase là một nền tảng di động giúp bạn nhanh chóng phát triển các ứng dụng chất lượng cao, phát triển ứng dụng cho người dùng lớn, và kiếm được ...
Võ Nhật Nam viết hơn 4 năm trước
14 6
{{like_count}}

kipalog

{{ comment_count }}

bình luận

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


Male avatar
{{userFollowed ? 'Following' : 'Follow'}}
447 bài viết.
78 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á!