Ionic 4, PWA, Firebase, le trio roi d’une appli web et mobile offline

Dans cet article vous allez découvrir comment réaliser une application web et mobile à l’aide de la technologie Ionic 4, PWA et Firebase, et qui fonctionne aussi en offline. Ayant construit plusieurs applications avec ces technologies, je vous apporterai un retour d’expérience. Allez, c’est parti !

Introduction aux technologies

IOnic est un framework très populaire, dont voici un petit rappel succinct: Ionic est un framework permettant de construire des applications mobiles hybrides pour Android ou IOS, en écrivant un seul code source. Le source code de l’application peut s’écrire en ReactJS ou en Angular. Le framework fournit un ensemble de plugin pour utiliser les composants natifs d’un périphérique mobile (caméra, GPS, accéléromètre …). L’application hybride peut s’installer via les app store. Une fois installée, l’application s’exécute via le moteur d’exécution du navigateur. Il s’agit donc d’une application web installé sur le périphérique.

En plus de permettre la fabrication d’application mobile, IOnic permet de construire une application dite PWA: Progressive Web Application. Les applications web PWA ont 2 avantages majeurs : La capacité d’être installable sans passer par un app store, et la capacité de fonctionner en mode déconnecté.

Enfin, le dernier élément technologique majeur de cet article est Firebase. Firebase est une solution de construction et d’hébergement d’application web et mobile. Elle est composée d’une base de données document (JSON), d’un hébergement de site web, d’une solution FaaS (Function), d’une solution d’authentification, d’une solution de messaging et même d’une solution de Machine Learning. Firebase, au départ indépendant, a été racheté par Google. L’intégration avec le Cloud Google est donc facilité.

Architecture de l’application

Dans cet article, nous vous proposons d’écrire une application composée des éléments suivants:

  • Un front end web et mobile écrit en Angular 7 et fonctionnant aussi en mode déconnecté,
  • Un backend REST et sa base de données JSON en Firebase,
  • Une authentification à base de la solution Firebase,
  • Un hébergement du site web est assuré par Firebase.

Attention, l’article part de l’hypothèse que vous avez les connaissances de bases en Angular.

Tutorial

Ce tutorial va vous aider à créer une application avec une architecture composée des éléments cités précédemment..

Création de l’application IOnic

La première étape consiste à créer une application IOnic. Le mieux est de suivre les instructions du Getting Started de IOnic :

Puis ajoutons les dépendances à Firebase, pour cela nous utilisons le plugin AngularFire2:

Création du projet dans Firebase

Pour que votre application ait sa base de données et son hébergement, il faut créer un projet dans Firebase. Tout d’abord, il vous faudra un compte sur Firebase . La version gratuite est bien suffisante pour faire des petits projets.
Lorsque vous aurez créé un compte dans la console Firebase console. Cliquez sur  Ajouter Projet, puis entrez un nom de projet. Cliquez sur Continuer, et finalement cliquez sur Créer projet.

Firebase provisionne alors automatiquement les ressources de votre projet. A la fin du processus, vous aurez accès à la page d’accueil de votre projet dans console Firebase.

Configuration de l’application IOnic pour votre projet Firebase

Une fois le projet créé, vous devez configurer l’application IOnic pour qu’elle utilise votre projet Firebase. Cela commence par ajouter des variables dans la “configuration environnement” de l’application IOnic. Ainsi, dans le fichier src/environment.ts ajoutez la configuration Firebase sous forme d’une constante :

Note: Les valeurs des champs sont accessibles dans la console Firebase.

Configuration du module

Pour cela, ouvrez le fichier de configuration du module src/app/app.module.ts, puis ajoutez la déclaration des modules Angular et le lien avec la configuration définie juste avant :

Maintenant, votre application IOnic est capable de discuter avec le backend Firebase, et est aussi capable de stocker les données sur le device (smartphone ou navigateur).

Persistance des données

Firebase propose du stockage de structure JSON dans des collections. C’est une BD NoSQL de type document. L’API est accessible en REST, mais le plus simple est d’utiliser l’API TypeScript de AngulareFire2 qui masque les appels REST.

Pour les données persistantes, j’ai choisi de structurer et de typer via des interfaces. Ce n’est bien sur pas obligatoire pour faire du Firebase , mais codons propre ! Ainsi, j’ai défini une interface mère de tous les objets métier persistant : PersistentData

Cela permet d’avoir, systématiquement dans un objet métier persistant, les éléments suivants : un identifiant (champ id string obligatoire dans Firebase ), une date de création, une date de mise à jour et un statut pour chaque objet persistant. J’ai aussi défini un service générique pour la persistance qui implémente cette interface CRUD :

Cette interface paramétrée permet aussi de définir une implémentation générique se basant sur firebase. Le code source étant un peu long, je vous propose le lien direct vers un fichier hébergé dans un projet sur GitHub RemotePersistentDataService.
Avec ces 2 éléments génériques, il devient très simple de rendre persistant un objet métier. Il suffit de créer une interface de son objet métier qui étende PersistentData. Voici un exemple d’un objet métier décrivant une compétition sportive:

Et de créer le service Angular étendant l’implémentation générique de l’interface CRUD :

Ce service étend le service générique RemotePersistentDataService. Il contient donc :

  • L’implémentation de la méthode getLocalStoragePrefix() indiquant le nom de la collection persistante,
  • Une méthode optionnelle adjustFieldOnLoad permettant d’ajuster l’objet métier lors de son chargement. Cela est nécessaire pour les champs de type date qui sont transformés en string dans la base Firebase,
  • Une méthode de recherche (query), ici getCompetitionByName() qui effectue la recherche d’un objet métier par un critère (le nom de la compétition).

Par héritage, ce service offre les méthodes CRUD vues plus haut pour lire, écrire, supprimer un objet métier, et rechercher tous les éléments de la collection. Une collection est créée automatiquement lors de la création du premier document JSON de la collection.

L’API AngulareFire2 décide seule d’accéder au serveur distant ou de consulter le cache. Elle regarde l’état de la connectivité et synchronise les données lorsque cela est nécessaire.

Ajouter l’aspect PWA

Une application capable de fonctionner en mode déconnecté, c’est bien, mais encore faut-il pouvoir lancer l’application en déconnecté. C’est là que PWA intervient ! En ajoutant l’aspect PWA à votre application, elle devient installable, c.a.d qu’une icone est présente sur le bureau/accueil de votre périphérique. Le principe est le suivant :

  • L’application est configurée en PWA,
  • Le navigateur télécharge l’application la première fois et met en cache les données (fichiers JS, HTML, images …),
  • Via un bouton développé dans l’application, l’utilisateur décidera de déclencher l’installation de l’application sur l’écran d’accueil (ou bureau),
  • L’utilisateur peut désormais lancer l’application via l’icone, sans requérir de réseau.

L’ajout de l’aspect PWA à votre application IOnic s’effectue par la simple commande suivante :

Cette commande ajoute un service worker dans l’application et un manifest pour la page web.

Comme IOS est toujours un peu particulier (Merci Apple 🙂 ), il convient de réaliser quelques autres tuning :

1) dans le fichier index.html ajouter les lignes suivantes dans la balise <head> :

Il s’agit d’indiquer à Safari les icônes à utiliser.

Maintenant que l’application est PWA, il faut offrir à l’utilisateur le moyen d’installer l’application via un bouton dans l’application. Ainsi, dans un composant de la page (par exemple la page d’accueil), ajoutons un bouton :

L’application est maintenant configurée pour le mode PWA. Avant chaque déploiement, il faudra compiler l’application avec l’option service-worker :

En la déployant comme un simple site web, elle pourra être installée sur le périphérique de l’utilisateur.

Gestion des utilisateurs

Firebase fournit une solution pour authentifier les utilisateurs des applications. Ainsi, le backend contient un service Firebase des utilisateurs de votre application. Ce n’est pas une base de données dans laquelle il est possible d’ajouter ses propres structures. Pour ajouter des champs spécifiques à l’application, il faut créer une collection des utilisateurs (voir le chapitre précédent). Ainsi, la création (et la suppression) d’un utilisateur dans le service Firebase doit être couplée avec la création d’un utilisateur applicatif. Ci-dessous, un exemple de code permettant de créer un utilisateur dans le service Firebase. Ce code est à brancher derrière un écran d’enregistrement d’un utilisateur sur votre application :

Voici un autre exemple de code permettant l’authentification à brancher derrière un écran de login de votre application :

Les deux fonctions ci-dessus sont généralement implémentées dans un service (ex UserService).
En plus du couple login/password, Firebase fournit aussi la possibilité d’enregistrer ou d’authentifier des utilisateurs via des sites bien connus : Google, Facebook, Microsoft, GitHub …

Déploiement de l’application avec Firebase

Le déploiement de l’application est très simple grace à la CLI Firebase qu’il faut installer la première fois :

Ensuite, il faut relier le projet IOnic au projet Firebase. Pour cela faite

La commande login va demander de s’authentifier sur une page web firebase.
La commande init sert à configurer ce que vous allez déployer dans votre projet Firebase. Elle pose un certain nombre de questions pour configurer le projet :
1) Choisissez Firestore pour le stockage BD, et surtout hosting pour l’hébergement du site web.

2) Ensuite, choisissez le projet Firebase que vous avez créé au début du tutoriel.
3) Pour le hosting, il faut spécifier le répertoire de compilation de IOnic, c.a.d build. Indiquer oui à SPA pour que les URLs soient récrites correctement en cas de refresh de la page Angular.

Maintenant que le déploiement est configuré, il ne reste plus qu’à lancer le déploiement :

Vous aurez sans doute remarqué des questions à propos de règle de protection de l’accès à la base de données via un fichier json. C’est dans ce fichier, ou dans la console web, que vous pouvez configurer la protection de l’accès aux collections. La protection minimale est bien souvent de permettre l’accès en lecture à des utilisateurs authentifiés seulement. Pour plus d’information, la lecture du guide Firestore est conseillée.

La fonction de hosting Firebase permet aussi d’utiliser son propre nom de domaine.

Retour d’expérience

Dans cet article, nous avons vu comment construire une application web mobile installable, et qui supporte le mode déconnecté. Faisons un peu le bilan.

Maîtrise du mode déconnecté

Tout d’abord, parlons du mode déconnecté. La synchronisation est entièrement pilotée de manière autonome par la librairie angular-fire2. La seule option de gestion manuel consiste à activer ou non le réseau :

En revanche, il n’est pas possible d’avoir des indicateurs sur les données restants à synchroniser, et celles en cours de synchronisation. En effet, lors de la modification d’une données sur le serveur, la fonction renvoie une promesse qui sera résolue lorsque l’action sera réalisée. Dans la promesse, il est facile de récupérer l’événement d’écriture. Cependant, les promesses ne fonctionnent plus dès que l’application est fermée puis relancée. Et pour une application mobile, c’est juste un cas de base. En effet, le code est remis à zero et les promesses sont oubliées. En revanche, les données sont bien synchronisées.
Il est courant dans les applications en mode déconnecté de permettre à l’utilisateur de contrôler la synchronisation, ou à minima, d’avoir une vue sur ce qu’il se passe. Là ce n’est pas possible.

Limitation du stockage

PWA permet de stocker des données sur le périphérique. Sur Android, la capacité n’est pas bridée, en revanche, sur IOS, la capacité de stockage est limitée à 50 Mo. Cette faible quantité est limitante pour les applications.

Application installable sauf sur IOS

PWA permet de rendre installable une application web. Ceci fonctionne assez bien sur Android. En revanche sur IOS, cela pose toujours problème : D’une part la fonctionnalité est plus difficilement accessible, et secondo cela ne fonctionne que sur les IOS récent. Il faut donc attendre encore quelques temps. Ainsi, Apple freine l’adoption du PWA car cela le priverait d’une partie de la manne financière que représente les revenus de l’app store.

Hébergement multi-site pratique

Une des bonnes surprise de Firebase hosting est la capacité d’héberger plusieurs sites dans le même projet. C’est par exemple très utile pour héberger le site statique promotionnel et documentaire, et en même temps, le site de l’application web mobile.

Industrialisation à parfaire

La CLI firebase et la CLI IOnic sont ultra intéressantes. En particulier, le simulateur (ou server) Ionic permet de debugger le code en direct. Un point d’amélioration serait une intégration plus forte des outils pour faciliter l’enchaînement des tâches. La solution réside dans l’usage d’un outil par dessus ces CLI. Grunt est une bonne solution.

Conclusion

Il est temps de conclure cet article. Clairement le trio IOnic, PWA et Firebase permet de réaliser de manière très simple, très rapide et peu cher des applications mobiles web avec du mode déconnecté. Il reste cependant 2 points d’améliorations notables : La faible maîtrise du mode déconnecté / synchronisation et l’installation facile de l’application sur IOS.

Leave a Reply

Your email address will not be published. Required fields are marked *