Angular4: User authentication with Firebase

Create user authentication with firebase

The purpose of this app is to show confirmed starting NHL goalies every day. The api provides a best guess and the actual starter does not get updated to until well into game time. This created a lot of false data being represented on this app. I created a system of indicators that work with a Boolean (true or false). If a NHL goalie is a guess then I will show an orange expected indicator in my app next to the goalie, if the NHL goalie has been confirmed by his team I will show a green confirmed indicator next to the goalie.

Since I could not rely on the api to update a confirmed starting goalie fast enough I needed to source my own data and update the goalie’s starting status manually. This means I made my own goalie json file and synced it to the api using each goalies ID with javascript for loops. I added an expected and confirmed attribute to each goalie when the app loads. Now I can update those attributes on the ng-model of each goalie and save it to my firebase DB. This will get me quicker updates and avoid showing false data by overriding the returned data from the api.

I created a small cms to allow me to update the goalies status by clicking on their image to toggle true or false. I created a view that can only be accessed by me so that a random user wouldn’t be able to make unwanted changes to my app. In order to lock off this cms admin zone just for me I used firebase to create a special user authentication token. If I use the correct name and password my cms will appear and I can make quick updates right in the view where I want to see them.

  • Create a firebase user by going to your firebase console and in the side nav under Develop click on the Authentication option.
  • In Authentication go to the SIGN-IN METHOD tab and enable Email/Password.
  • Then click on USERS tab and click ADD USER button. Enter an email and password.
  • Set up firebase in angular4 app (follow first part of this link).
  • Make a firbase service to handle saving data and retrieving data from the db.
  
  //firebase.service.ts

import { Injectable } from '@angular/core';
import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';
import { AngularFireAuth } from 'angularfire2/auth';
import { Observable } from 'rxjs/Observable';
import * as firebase from 'firebase/app';

@Injectable()
export class FirebaseService {

  items:FirebaseListObservable<any[]>;
  private user: Observable<firebase.User>;
  private userDetails: firebase.User = null;

  constructor(public af: AngularFireDatabase, private firebaseAuth: AngularFireAuth) {
    this.items = af.list('/items'); 
    this.user = firebaseAuth.authState;

      this.user.subscribe(
          (user) => {
            if (user) {
              this.userDetails = user;
            }
            else {
              this.userDetails = null;
            }
          }
        );
    
  }

 signInRegular(email, password) {
   const credential = firebase.auth.EmailAuthProvider.credential( email, password );
   return this.firebaseAuth.auth.signInWithEmailAndPassword(email, password)
 }


  logout() {
    this.firebaseAuth.auth.signOut();
  }


  getData() {
    console.log('getting starter data from firebase...');
    return this.items = this.af.list('/items');
  }
}

  • Include the firbase service in the app.module.ts in providers.
  • Define the user model in the app.component.ts, create a function and call the function from the html form.
//app.component.ts

import { Component, OnInit } from '@angular/core';
import { FirebaseService } from '../firebase.service';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {

// USER MODEL
user = {
        email: '',
        password: ''
       };
  
  constructor(private fbService: FirebaseService){}

  public signInWithEmail() {
    this.fbService.signInRegular(this.user.email, this.user.password)
      .then((res) => {
        //success
      })
      .catch((err) => console.log('error: ' + err));
  }


  ngOnInit() {
     
    
  }

}
<!-- app.component.html -->

<div class="login-container">
 
  <input type="email" class="form-control" [(ngModel)]="user.email" placeholder="Email" required>
  
  <input type="password" class="form-control" [(ngModel)]="user.password" placeholder="Password" required>

  <button (click)="signInWithEmail()">Login</button>

</div> 

The key here is in the firebase service this.firebaseAuth.auth.signInWithEmailAndPassword(email, password) This specifically talks to firebase. If the email and password are correct firebase will return a user object and it can be detected from the firebase service and can be used to show/hide add/edit/delete data features in the client. Using the same html form I can use fbService.userDetails to hide the log in form and show the log out button to end the session.

<!-- app.component.html -->

<div class="login-container" *ngIf="fbService.userDetails == null">
 
  <input type="email" class="form-control" [(ngModel)]="user.email" placeholder="Email" required>
  
  <input type="password" class="form-control" [(ngModel)]="user.password" placeholder="Password" required>

  <button (click)="signInWithEmail()">Login</button>

</div> 

 
<div *ngIf="fbService.userDetails != null">
 <button (click)="fbService.logout()">Logout</button>
</div>

In the next article I will expand a bit more on how to use the user authentication to create an admin area to edit data and update the view in realtime without refreshing the page. Angular4: Update Data Realtime with Firebase

Check the codebase on my GitHub account!