Bonjour à tous! Dans ce tutoriel Ionic 4 et Firebase, nous allons voir comment récupérer et afficher des images stockées dans Firebase dans Ionic.

C’est un tuto que vous avez été un certain nombre à me demander, car il complète le tuto sur l’upload de photos dans Firebase et du plugin Camera: https://drissas.com/ionic-camera-plugin/

Cette fonctionnalité vous permettra par exemple de créer un fil d’actualité dans une application, de partager des photos dans un chat ou encore d’utiliser une photo de profil.

Les images et les photos sont omniprésentes dans les applications, il est donc important d’apprendre à les manipuler et surtout de gérer leur gestion depuis Firebase.

Firebase nous permet en effet de stocker toutes sorte de fichiers dont des images, que nous allons apprendre à récupérer et afficher le plus simplement possible.

Pour suivre correctement ce tuto, vous avoir installé au préalable le plugin AngularFire: https://drissas.com/ionic-4-firebase/

Nous allons donc suivre les étapes suivantes pour réaliser l’affichage de photos issues de Firebase:

  1. Créer une table dans la base de données
  2. Stocker des images dans la base de stockage Firebase
  3. Récupérer les informations des images
  4. Générer l’URL des images de Firebase dans Ionic
  5. Afficher les images de Firebase dans Ionic

Comment créer une table dans la base de données ?

On commence ce tuto par la création d’une table dans notre base de données Firebase.

Si ce n’est pas déjà fait, créez un projet Firebase et rendez-vous dans la section Database: https://firebase.google.com/

Nous allons ainsi créer une table pour contenir toutes les données en rapport avec nos différentes images.

Voilà à quoi ressemble notre table de trois images:

Pour chaque image dans la base de données, on stocke son nom ainsi que son adresse dans la base de stockage.

Nous allons par la suite télécharger nos images dans la base de stockage, et plus précisément dans un dossier appelé « Images ».

Créez donc une table similaire d’images avec comme adresse le dossier Images/ suivi du nom de l’image que nous allons uploader.

Comment stocker des images dans la base de stockage Firebase ?

Maintenant que notre table Firebase est créée, nous allons importer nos images dans Firebase.

Rendez-vous pour cela dans le menu Storage à gauche de votre tableau de bord Firebase:

Cliquez ensuite sur Commencer pour générer votre base de stockage, qui se présente comme espace dans votre ordinateur.

Vous retrouvez en effet vos différent fichiers ainsi que des dossiers:

Dans ce tutoriel Ionic, nous allons créer un dossier « Images/ » pour stocker toutes nos images pour comprendre le fonctionnement de Firebase.

Dans vos applications, vous aurez un dossier pour tous les types de fichiers, par exemple le dossier « Users/ » pour stocker les photos de profil de vos utilisateurs.

Créez ainsi le dossier « Images/ » puis ouvrez-le par la même occasion. Cliquez ensuite sur le bouton « Importer un fichier » pour uploader vos différentes images.

C’est maintenant terminée, notre base de stockage est opérationnelle, il ne nous reste plus qu’à travailler sur Ionic.

Comment récupérer les informations des images ?

Dans un premier temps, nous allons travailler avec la base de données Firebase, pour récupérer les différentes informations de nos images.

Pour utiliser Firebase, nous allons utiliser le plugin AngularFire dont je vous laisse la documentation officielle: https://github.com/angular/angularfire

Si ce n’est pas déjà fait, installer le plugin avec la commande suivante:

npm install firebase @angular/fire --save

Puis rendez-vous dans le fichier globale suivant:

src/app/app.module.ts

Dans ce fichier, nous allons importer et déclarer tous les plugins et modules dont nous allons avoir besoin.

En l’occurrence ici nous aurons besoin des trois modules suivants:

import { AngularFireModule } from '@angular/fire'; // pour se connecter à Firebase
import { AngularFireDatabaseModule } from '@angular/fire/database'; // pour manipuler la base de données Firebase
import { AngularFireStorageModule } from '@angular/fire/storage'; // pour accéder aux fonction de stockage et de récupération des fichiers

Vous pouvez ensuite si ce n’est pas déjà fait déclarer vos codes de configuration Firebase:

export const firebaseConfig = {
  apiKey: '*****************************-***',
  authDomain: '***********.firebaseapp.com',
  databaseURL: 'https://***********.firebaseio.com',
  projectId: '***********',
  storageBucket: '***********.appspot.com', // <-- nouvelle donnée
  messagingSenderId: '***********',
  appId: '*:***********:web:***********'
};

Attention: si votre base de stockage n’était pas activé par le passé, nous n’aurez pas le storageBucket de rempli.

Si ce champ est vide pour le moment, prenez soin de récupérer à nouveaux vos codes de configuration pour obtenir le champ manquant.

Vous pouvez ensuite déclarer ces trois modules dans le tableau imports:

imports: [
  BrowserModule,
  IonicModule.forRoot(),
  AppRoutingModule,
  AngularFireModule.initializeApp(firebaseConfig),
  AngularFireDatabaseModule,
  AngularFireStorageModule
]

On peut maintenant se rendre dans notre page d’accueil pour accéder aux données de nos images. Pour cela commencez par ouvrir le fichier:

src/app/home/home.page.ts

Puis importer les deux modules dont nous utiliserons les fonction, celui des base de données et de la base de stockage:

import { AngularFireDatabase } from '@angular/fire/database';
import { AngularFireStorage } from '@angular/fire/storage';

Déclarez ensuite ces deux modules dans le constructor pour pouvoir accéder à leur différentes fonctions:

constructor(
    public afDB: AngularFireDatabase,
    public afSG: AngularFireStorage
  ) {}

Pour récupérer nos informations, nous travaillerons en deux temps, avec une fonction pour chaque type de récupération de données:

getImagesDatabase() {
  // pour récupérer les informations des images
}

getImagesStorage() {
  // pour récupérer l'URL des images
}

On commence donc par récupérer les informations de nos images dans la base de données. Pour cela on utilise le plugin AngularFireDatabase et sa fonction list() pour accéder aux données de notre table « Images »:

this.afDB.list('Images').snapshotChanges(['child_added']).subscribe(images => {
  console.log(images);
});

Cette première structure nous permet de récupérer toutes les données de notre table « Images » dans notre base de données.

Notez également que nous nous sommes abonné à l’évènement ‘child_added’ ce qui veut dire que nous récupèrerons le contenu de la table « Images » à chaque ajout d’un élément dans celle-ci.

On reprend donc le résultat renvoyé par notre fonction list() et on le parcourt pour ne récupérer les informations d’une seule image à la fois:

this.afDB.list('Images').snapshotChanges(['child_added']).subscribe(images => {
  images.forEach(image => {
    console.log('Image: ' + image.payload.exportVal().name);
  });
});

Ici on affiche dans la console le non de chaque image une par une. Nous sommes également capables de la faire pour d’autres informations, par exemple la référence de l’image dans la base de stockage:

this.afDB.list('Images').snapshotChanges(['child_added']).subscribe(images => {
  images.forEach(image => {
    console.log('Ref de l\'image: ' + image.payload.exportVal().ref);
  });
});

Nous venons donc de voir comment récupérer les informations de nos images dans la base de données. Passons donc à la récupération de l’URL de celles-ci.

Comment générer l’URL des images de Firebase dans Ionic ?

Cette fois-ci, nous allons utiliser le module AngularFireStorage pour utiliser précisément une de ces fonctions. Cette fonction s’appelle getDownloadURL() et va nous permettre de générer une URL pour chaque fichier de notre base de stockage.

Prenons un exemple simple, pour récupérer l’URL de ma photo d’Iron Man, voilà le code que je dois utiliser:

this.afSG.ref('/Images/iron-man.png').getDownloadURL().subscribe(imgUrl => {
  console.log(imgUrl);
});

Ce bout de code me permet d’afficher dans la console l’URL de n’importe quel fichier de ma base de stockage, à condition de lui indiquer la référence exacte de celui-ci.

Nous souhaitons maintenant récupérer la référence de chaque image de notre base de stockage, pour cela nous allons travailler avec les paramètres des fonctions JavaScript.

On reprend notre fonction getImagesStorage() et on lui ajoute la paramètre suivant:

getImagesStorage(image: any) {}

On lui ajoute le paramètre que l’on appelle « image », qui sera en fait l’objet qui contiendra toutes les informations sur celle-ci, notamment son nom et surtout sa référence dans la base.

De cette manière on peut transmettre à notre fonction getImagesStorage() toutes les informations de notre image depuis la fonction précédente getImagesDatabase():

getImagesDatabase() {
  this.afDB.list('Images').snapshotChanges(['child_added']).subscribe(images => {
    images.forEach(image => {
      this.getImagesStorage(image);
    });
  });
}

Au passage on créé une nouvelle variable globale à notre page, pour pouvoir stocker toutes les informations de nos images:

export class HomePage {
  images = [];

On déclare cette variable sous forme de tableau pour pouvoir stocker différents objets (un pour chaque image) à l’intérieur.

On développe maintenant un peu plus notre fonction getImagesStorage() pour récupérer les informations transmises:

getImagesStorage(image: any) {
  const imgRef = image.payload.exportVal().ref;
  this.afSG.ref(imgRef).getDownloadURL().subscribe(imgUrl => {
    console.log(imgUrl);
  });
}

Avec cette structure on stocke en premier lieu la référence de notre image dans une variable temporaire imgRef. Puis on génère l’URL de cette image précise avec la fonction getDownloadURL() du module AngularFireStorage.

Nous avons maintenant accès à toutes les informations qui nous intéressaient. Nous pouvons passer à la dernière étape de notre fonction qui est de stocker ces informations.

On reprend en effet notre variable images (un tableau) et on lui ajoute pour chaque image rencontré dans la base de données les deux informations qui nous intéressent (nom et URL):

this.images.push({
  name: image.payload.exportVal().name,
  url: imgUrl
});

Vous pouvez ainsi compléter votre fonction getImagesStorage() comme ceci:

getImagesStorage(image: any) {
  const imgRef = image.payload.exportVal().ref;
  this.afSG.ref(imgRef).getDownloadURL().subscribe(imgUrl => {
    console.log(imgUrl);
    this.images.push({
      name: image.payload.exportVal().name,
      url: imgUrl
    });
  });
}

De cette manière, nous récupérons et stockons toutes les informations utiles de nos images (nom et URL) dans le tableau images.

Comment afficher les images de Firebase dans Ionic ?

On termine ce tutoriel Ionic 4 et Firebase avec la possibilité de parcourir et d’afficher nos différentes images.

Pour cela, nous allons utiliser la directive ngFor pour parcourir notre tableau de données, en l’occurrence notre tableau images:

*ngFor="let image of images"

À chaque objet rencontré, on renvoie l’objet image que nous pouvons à son tour lire, et afficher en détail ces informations, par exemple son nom:

{{ image.name }}

Pour faire au plus simple, on peut commencer par n’afficher que le nom de notre image, avec le code suivant:

<ion-card *ngFor="let image of images">
  <ion-card-header>
    <ion-card-subtitle>{{ image.name }}</ion-card-subtitle>
  </ion-card-header>
</ion-card>

J’ai placé notre contenu dans des cartes pour bien visualiser leur séparation. On les complète donc avec l’affiche de nos images, avec la balise suivante:

<ion-img [src]="image.url"></ion-img>

Attention toutefois, cette-fois nous mettons notre variable dans un attribut, qui doit donc être entre croché pour faire référence à une variable.

Le résultat final de votre carte ionic est donc le suivant:

<ion-card *ngFor="let image of images">
  <ion-img [src]="image.url"></ion-img>
  <ion-card-header>
    <ion-card-subtitle>{{ image.name }}</ion-card-subtitle>
  </ion-card-header>
</ion-card>