• 20 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 28/11/2019

Intégrez un backend - création et authentification

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Pour ce cours, vous allez configurer un backend avec le service Firebase de Google.  Ce service permet la création d'un backend complet sans coder et comprend énormément de services, dont l'authentification et une base de données NoSQL.

Créez un backend Firebase

Allez à firebase.google.com, créez un compte Google ou authentifiez-vous si vous en avez déjà un, et créez un nouveau projet Firebase.  Vous pouvez le domicilier dans votre pays de résidence et lui donner le nom que vous voulez.

Ensuite, installez Firebase dans votre projet avec NPM :

npm install firebase -- save

La console Firebase vous propose le choix suivant (sous la rubrique Overview) :

Choisissez "Ajouter Firebase à votre application Web" et copiez-collez la configuration dans le constructeur de votre  AppComponent  (en ajoutant  import * as firebase from 'firebase';  en haut du fichier mettant à disposition la méthode  initializeApp() ) :

import { Component, ViewChild } from '@angular/core';
import { MenuController, NavController, Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

import * as firebase from 'firebase';

import { TabsPage } from '../pages/tabs/tabs';
import { OptionsPage } from '../pages/options/options';
@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  tabsPage:any = TabsPage;
  optionsPage:any = OptionsPage;
  @ViewChild('content') content: NavController;

  constructor(platform: Platform,
              statusBar: StatusBar,
              splashScreen: SplashScreen,
              private menuCtrl: MenuController) {
    platform.ready().then(() => {
      statusBar.styleDefault();
      splashScreen.hide();
      let config = {
        apiKey: "AIzaSyDHOgsghqV5cIdpyrhXEmmtkaAroVNsfG4",
        authDomain: "openclassrooms-ionic.firebaseapp.com",
        databaseURL: "https://openclassrooms-ionic.firebaseio.com",
        projectId: "openclassrooms-ionic",
        storageBucket: "openclassrooms-ionic.appspot.com",
        messagingSenderId: "121353569465"
      };
      firebase.initializeApp(config);
    });
  }

  onNavigate(page: any) {
    this.content.setRoot(page);
    this.menuCtrl.close();
  }
}

Votre application Ionic est maintenant liée à votre projet Firebase et vous pourrez désormais intégrer les services d'authentification et de base de données.

Authentification

Votre application utilisera l'authentification par adresse mail et mot de passe proposée par Firebase afin de sécuriser votre base de données.  Pour cela, il faut d'abord l'activer dans la console Firebase :

Avant de créer une page pour l'authentification, vous allez créer le service  AuthService  qui comportera les méthodes dont vous aurez besoin.  Commencez par créer un boolean qui sera lié à l'état d'authentification retourné par Firebase :

import * as firebase from 'firebase';

export class AuthService {
  isAuth = false;

  constructor() {
    firebase.auth().onAuthStateChanged((user) => {
      if (user) {
        this.isAuth = true;
      } else {
        this.isAuth = false;
      }
    });
  }
}

Ensuite, créez une méthode pour l'inscription d'un nouvel utilisateur et une autre pour la connexion d'un utilisateur existant.  Ces deux méthodes seront asynchrones, puisque les méthodes qu'elles appellent chez Firebase le sont également :

  signUpUser(email: string, password: string) {
    return new Promise((resolve, reject) => {
      firebase.auth().createUserWithEmailAndPassword(email, password).then(
        (user) => {
          resolve(user);
        },
        (error) => {
          reject(error);
        }
      );
    });
  }

  signInUser(email: string, password: string) {
    return new Promise((resolve, reject) => {
      firebase.auth().signInWithEmailAndPassword(email, password).then(
        (user) => {
          resolve(user);
        },
        (error) => {
          reject(error);
        }
      );
    });
  }

Enfin, créez une méthode pour la déconnexion de l'utilisateur connecté :

signOut() {
    firebase.auth().signOut();
}

Maintenant que le service est prêt, vous pouvez l'ajouter à l'array providers de votre  AppModule

Créez un sous-dossier  auth  du dossier  pages  qui contiendra la page gérant l'inscription et la connexion des utilisateurs.  Comme d'habitude, créez des fichiers TypeScript, SCSS et template pour la page.

Cette page s'occupera des deux actions : l'inscription d'un nouvel utilisateur et la connexion d'un utilisateur déjà existant.  Il faudra donc y injecter au moins  AuthService  pour les méthodes liées à l'authentification, et  NavParams  afin de récupérer le mode (que vous lui passerez depuis l'extérieur selon le bouton cliqué par l'utilisateur) :

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

@Component({
  selector: 'page-auth',
  templateUrl: './auth.html'
})
export class AuthPage implements OnInit {

  constructor(private authService: AuthService,
              private navParams: NavParams) {}

  ngOnInit() {}
}

Pour définir le mode de cette page, vous allez créer une variable de type  string  et l'initialiser dans  ngOnInit()  en récupérant le mode dans les  NavParams  (que vous implémenterez par la suite) :

export class AuthPage implements OnInit {

  mode: string;

  constructor(private authService: AuthService,
              private navParams: NavParams) {}

  ngOnInit() {
    this.mode = this.navParams.get('mode');
  }
}

Il y aura deux modes :  new  et  connect .  Vous pouvez commencer à créer le template en prenant cela en compte :

<ion-header>
  <ion-navbar>
    <ion-buttons start>
      <button ion-button icon-only (click)="onToggleMenu()">
        <ion-icon name="menu"></ion-icon>
      </button>
    </ion-buttons>
    <ion-title *ngIf="mode === 'new'">Nouvel utilisateur</ion-title>
    <ion-title *ngIf="mode === 'connect'">Connexion</ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>

</ion-content>

Ajoutez dès maintenant la méthode  onToggleMenu()  comme ailleurs, en injectant  MenuController . Ajoutez également cette nouvelle page à votre  AppModule  afin de pouvoir vous y rendre.

L'objectif est de pouvoir accéder à cette page depuis le menu latéral de l'application.  Pour l'instant, dans  app.component.ts  , la méthode  onNavigate()  ne permet pas d'envoyer des données vers une page.  Il suffit de la modifier légèrement :

onNavigate(page: any, data?: {}) {
    this.content.setRoot(page, data ? data : null);
    this.menuCtrl.close();
}

Ajoutez  AuthPage  comme propriété :

import { TabsPage } from '../pages/tabs/tabs';
import { OptionsPage } from '../pages/options/options';
import { AuthPage } from '../pages/auth/auth';
@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  tabsPage:any = TabsPage;
  optionsPage:any = OptionsPage;
  authPage:any = AuthPage;
  @ViewChild('content') content: NavController;

Et ajoutez les deux boutons correspondant au menu dans le template :

<ion-list>
      <button ion-item icon-start (click)="onNavigate(tabsPage)">
        <ion-icon name="power"></ion-icon>
        Appareils
      </button>
      <button ion-item icon-start (click)="onNavigate(optionsPage)">
        <ion-icon name="options"></ion-icon>
        Options
      </button>
      <button ion-item icon-start (click)="onNavigate(authPage, {mode: 'new'})">
        <ion-icon name="person-add"></ion-icon>
        Nouvel utilisateur
      </button>
      <button ion-item icon-start (click)="onNavigate(authPage, {mode: 'connect'})">
        <ion-icon name="person"></ion-icon>
        Connexion
      </button>
</ion-list>

Maintenant, vous allez créer le component pour  AuthPage . Commencez par créer le formulaire (vous utiliserez ici la méthode réactive).  Créez l'objet  authForm  de type  FormGroup  , injectez  FormBuilder , créez la méthode  initForm()  qui initialise le formulaire et exécutez cette méthode dans  ngOnInit()  :

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../services/auth.service';
import { MenuController, NavParams } from 'ionic-angular';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'page-auth',
  templateUrl: './auth.html'
})
export class AuthPage implements OnInit {

  mode: string;
  authForm: FormGroup;

  constructor(private authService: AuthService,
              private navParams: NavParams,
              private menuCtrl: MenuController,
              private formBuilder: FormBuilder) {}

  ngOnInit() {
    this.mode = this.navParams.get('mode');
    this.initForm();
  }

  onToggleMenu() {
    this.menuCtrl.open();
  }

  initForm() {
    this.authForm = this.formBuilder.group({
      email: ['', [Validators.required, Validators.email]],
      password: ['', Validators.required]
    });
  }
}

Vous pouvez maintenant créer le formulaire dans le template :

<ion-content padding>
  <form [formGroup]="authForm">
    <ion-list>
      <ion-item>
        <ion-label floating>Adresse mail</ion-label>
        <ion-input type="email" formControlName="email"></ion-input>
      </ion-item>
      <ion-item>
        <ion-label floating>Mot de passe</ion-label>
        <ion-input type="password" formControlName="password"></ion-input>
      </ion-item>
    </ion-list>
  </form>
</ion-content>

Pour soumettre ce formulaire, il faudra une méthode capable de prendre en compte le mode de la page et d'exécuter la méthode correspondante de  AuthService .  Pour cela, injectez  NavController  et  TabsPage , car si la connexion réussit, l'utilisateur sera redirigé vers la  TabsPage . Créez également une propriété  errorMessage  qui sera affichée au cas où l'inscription ou la connexion échoue :

  onSubmitForm() {
    const email = this.authForm.get('email').value;
    const password = this.authForm.get('password').value;
    if (this.mode === 'new') {
      this.authService.signUpUser(email, password).then(
        () => {
          this.navCtrl.setRoot(TabsPage);
        },
        (error) => {
          this.errorMessage = error;
        }
      );
    } else if (this.mode === 'connect') {
      this.authService.signInUser(email, password).then(
        () => {
          this.navCtrl.setRoot(TabsPage);
        },
        (error) => {
          this.errorMessage = error;
        }
      );
    }
  }

Ainsi, vous pouvez ajouter le bouton et le message d'erreur au template :

<form [formGroup]="authForm">
    <ion-list>
      <ion-item>
        <ion-label floating>Adresse mail</ion-label>
        <ion-input type="email" formControlName="email"></ion-input>
      </ion-item>
      <ion-item>
        <ion-label floating>Mot de passe</ion-label>
        <ion-input type="password" formControlName="password"></ion-input>
      </ion-item>
    </ion-list>
    <button ion-button full (click)="onSubmitForm()">Soumettre</button>
    <span ion-text color="danger">{{ errorMessage }}</span>
</form>

La directive  ion-text  permet à Ionic de lire l'attribut  color  afin d'appliquer la couleur choisie.

Il faudrait également que le menu affiche dynamiquement les éléments selon l'état d'authentification de l'utilisateur.  On pourrait penser qu'injecter  AuthService  dans  app.component.ts  nous le permettrait, mais puisque l'application n'est pas liée à Firebase avant l'appel du constructor — elle n'est pas encore initialisée —, il faut donc appeler la méthode  onAuthStateChanged()  directement depuis ce constructor (créez également une propriété locale  isAuth  pour stocker le statut d'authentification) :

platform.ready().then(() => {
      statusBar.styleDefault();
      splashScreen.hide();
      let config = {
        apiKey: "AIzaSyDHOgsghqV5cIdpyrhXEmmtkaAroVNsfG4",
        authDomain: "openclassrooms-ionic.firebaseapp.com",
        databaseURL: "https://openclassrooms-ionic.firebaseio.com",
        projectId: "openclassrooms-ionic",
        storageBucket: "openclassrooms-ionic.appspot.com",
        messagingSenderId: "121353569465"
      };
      firebase.initializeApp(config);
      firebase.auth().onAuthStateChanged(
        (user) => {
          if (user) {
            this.isAuth = true;
            this.content.setRoot(TabsPage);
          } else {
            this.isAuth = false;
            this.content.setRoot(AuthPage, {mode: 'connect'});
          }
        }
      );
    });

Dans le template du menu, vous pouvez maintenant ajouter  *ngIf="isAuth"  aux boutons Appareils et Options, et  *ngIf=!isAuth"  aux boutons Nouvel utilisateur et Connexion afin d'afficher de manière dynamique ces boutons :

    <ion-list>
      <button ion-item icon-start (click)="onNavigate(tabsPage)" *ngIf="isAuth">
        <ion-icon name="power"></ion-icon>
        Appareils
      </button>
      <button ion-item icon-start (click)="onNavigate(optionsPage)" *ngIf="isAuth">
        <ion-icon name="options"></ion-icon>
        Options
      </button>
      <button ion-item icon-start (click)="onNavigate(authPage, {mode: 'new'})" *ngIf="!isAuth">
        <ion-icon name="person-add"></ion-icon>
        Nouvel utilisateur
      </button>
      <button ion-item icon-start (click)="onNavigate(authPage, {mode: 'connect'})" *ngIf="!isAuth">
        <ion-icon name="person"></ion-icon>
        Connexion
      </button>
    </ion-list>

Il ne reste plus qu'à intégrer la déconnexion de l'utilisateur.  Pour les mêmes raisons que ci-dessus, vous ne pouvez pas appeler la méthode que vous avez créée dans  AuthService  : il faudra donc créer une méthode dans  app.component.ts  et ajouter un bouton au menu :

  onDisconnect() {
    firebase.auth().signOut();
    this.menuCtrl.close();
  }
      <button ion-item icon-start (click)="onNavigate(authPage, {mode: 'connect'})" *ngIf="!isAuth">
        <ion-icon name="person"></ion-icon>
        Connexion
      </button>
      <button ion-item icon-start (click)="onDisconnect()" *ngIf="isAuth">
        <ion-icon name="exit"></ion-icon>
        Déconnexion
      </button>

Avec cette dernière étape, l'authentification est totalement intégrée à votre application.  Ainsi, grâce aux méthodes mises à disposition par Firebase, votre application pourra accéder sans problème à la base de données.

Exemple de certificat de réussite
Exemple de certificat de réussite