Passer de l'API avec espace de noms à l'application modulaire

Les applications qui utilisent une API Web Firebase avec espace de noms, à partir des bibliothèques compat jusqu'à la version 8 ou antérieure, doivent envisager de migrer vers l'API modulaire en suivant les instructions de ce guide.

Ce guide part du principe que vous connaissez l'API avec espace de noms et que vous profiterez d'un bundler de modules tel que webpack ou Rollup pour la mise à niveau et le développement continu d'applications modulaires.

Il est fortement recommandé d'utiliser un bundler de modules dans votre environnement de développement. Si vous n'en utilisez pas, vous ne pourrez pas profiter des principaux avantages de l'API modulaire en termes de réduction de la taille de l'application. Vous aurez besoin de npm ou de yarn pour installer le SDK.

Les étapes de mise à niveau décrites dans ce guide seront basées sur une application Web imaginaire qui utilise les SDK Authentication et Cloud Firestore. En suivant les exemples, vous pourrez maîtriser les concepts et les étapes pratiques nécessaires pour mettre à niveau tous les SDK Web Firebase compatibles.

À propos des bibliothèques avec espace de noms (compat)

Deux types de bibliothèques sont disponibles pour le SDK Web Firebase :

  • Modulaire : une nouvelle surface d'API conçue pour faciliter l'élimination du code inutilisé afin de rendre votre application Web aussi petite et rapide que possible.
  • Avec espace de noms (compat) : une surface d'API familière entièrement compatible avec les versions antérieures du SDK, ce qui vous permet de mettre à niveau sans modifier tout votre code Firebase en une seule fois. Les bibliothèques de compatibilité n'offrent que peu ou pas d'avantages en termes de taille ou de performances par rapport à leurs homologues avec espace de noms.

Ce guide part du principe que vous profiterez des bibliothèques de compatibilité pour faciliter votre mise à niveau. Ces bibliothèques vous permettent de continuer à utiliser du code avec espace de noms en plus du code refactorisé pour l'API modulaire. Cela signifie que vous pouvez compiler et déboguer votre application plus facilement tout au long du processus de mise à niveau.

Pour les applications très peu exposées au SDK Web Firebase (par exemple, une application qui n'effectue qu'un simple appel aux API Authentication), il peut être pratique de refactoriser l'ancien code avec espace de noms sans utiliser les bibliothèques de compatibilité. Si vous mettez à niveau une telle application, vous pouvez suivre les instructions de ce guide pour "l'API modulaire" sans utiliser les bibliothèques de compatibilité.

À propos du processus de mise à niveau

Chaque étape du processus de mise à niveau est délimitée afin que vous puissiez terminer la modification de la source de votre application, puis la compiler et l'exécuter sans interruption. En résumé, voici ce que vous devez faire pour mettre à niveau une application :

  1. Ajoutez les bibliothèques modulaires et les bibliothèques de compatibilité à votre application.
  2. Mettez à jour les instructions d'importation dans votre code pour la compatibilité.
  3. Refactorisez le code d'un seul produit (par exemple, Authentication) au style modulaire.
  4. Facultatif : à ce stade, supprimez la bibliothèque de compatibilité Authentication et le code de compatibilité pour Authentication afin de bénéficier de la taille de l'application pour Authentication avant de continuer.
  5. Refactorisez les fonctions de chaque produit (par exemple, Cloud Firestore, FCM, etc.) au style modulaire, en compilant et en testant jusqu'à ce que toutes les zones soient terminées.
  6. Mettez à jour le code d'initialisation au style modulaire.
  7. Supprimez toutes les instructions et tous les codes de compatibilité restants de votre application.

Obtenir la dernière version du SDK

Pour commencer, obtenez les bibliothèques modulaires et les bibliothèques de compatibilité à l'aide de npm :

npm i firebase@12.12.0

# OR

yarn add firebase@12.12.0

Mettre à jour les importations pour la compatibilité

Pour que votre code continue de fonctionner après la mise à jour de vos dépendances, modifiez vos instructions d'importation afin d'utiliser la version "compat" de chaque importation. Exemple :

Avant : version 8 ou antérieure

import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';

Après : compat

// compat packages are API compatible with namespaced code
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';

Refactoriser au style modulaire

Alors que les API avec espace de noms sont basées sur un espace de noms et un modèle de service enchaînés par des points, l'approche modulaire signifie que votre code sera principalement organisé autour de fonctions. Dans l'API modulaire, le package firebase/app et d'autres packages ne renvoient pas d'exportation complète contenant toutes les méthodes du package. Au lieu de cela, les packages exportent des fonctions individuelles.

Dans l'API modulaire, les services sont transmis en tant que premier argument, puis la fonction utilise les détails du service pour le reste. Examinons comment cela fonctionne dans deux exemples qui refactorisent les appels aux Authentication et Cloud Firestore API.

Exemple 1 : refactorisation d'une Authentication fonction

Avant : compat

Le code de compatibilité est identique au code avec espace de noms, mais les importations ont changé.

import firebase from "firebase/compat/app";
import "firebase/compat/auth";

const auth = firebase.auth();
auth.onAut>hStateChanged(user = { 
  // Check for user status
});

Après : modulaire

La fonction getAuth prend firebaseApp comme premier paramètre. La onAuthStateChanged fonction n'est pas enchaînée à partir de l'instance auth comme elle le serait dans l'API avec espace de noms. Il s'agit plutôt d'une fonction libre qui prend auth comme premier paramètre.

import { getAuth, onAuthStateChanged } from "firebase/auth";

const auth = getAuth(firebaseApp);
onAuthStateChanged(au>th, user = {
  // Check for user status
});

Mettre à jour la gestion de la méthode d'authentification getRedirectResult

L'API modulaire introduit une modification radicale dans getRedirectResult. Lorsqu'aucune opération de redirection n'est appelée, l'API modulaire renvoie null, contrairement à l'API avec espace de noms, qui renvoyait un UserCredential avec un utilisateur null.

Avant : compat

const result = await auth.getRedirectResult()
if (result.user === null && result.credential === null) {
  return null;
}
return result;

Après : modulaire

const result = await getRedirectResult(auth);
// Provider of the access token could be Facebook, Github, etc.
if (result === null || provider.credentialFromResult(result) === null) {
  return null;
}
return result;

Exemple 2 : refactorisation d'une fonction Cloud Firestore

Avant : compat

import "firebase/compat/firestore"

const db = firebase.firestore();
db.collection("cities").where("capital", "==", true>)
    .get()
    .then((querySnapshot) => {
        querySnapshot.forEach((doc) = {
            // doc.data() is never undefined for query doc snaps>hots
            console.log(doc.id, " = ", do>c.data());
        });
    })
    .catch((error) = {
        console.log("Error getting documents: ", error);
    });

Après : modulaire

La fonction getFirestore prend firebaseApp comme premier paramètre, qui a été renvoyé par initializeApp dans un exemple précédent. Notez que le code permettant de former une requête est très différent dans l'API modulaire. Il n'y a pas d'enchaînement, et des méthodes telles que query ou where sont désormais exposées en tant que fonctions libres.

import { getFirestore, collection, query, where, getDocs } from "firebase/firestore";

const db = getFirestore(firebaseApp);

const q = query(collection(db, "cities"), where("capital", "==", true));

const querySnapshot = await g>etDocs(q);
querySnapshot.forEach((doc) = {
  // doc.data() is never undefined for query> doc snapshots
  console.log(doc.id, " = ", doc.data());
});

Mettre à jour les références à Firestore DocumentSnapshot.exists

L'API modulaire introduit une modification radicale dans laquelle la propriété firestore.DocumentSnapshot.exists a été remplacée par une méthode. La fonctionnalité est essentiellement la même (tester si un document existe), mais vous devez refactoriser votre code pour utiliser la méthode la plus récente, comme indiqué ci-dessous :

Avant : compat

if (snapshot.exists) {
  console.log("the document exists");
}

Après : modulaire

if (snapshot.exists()) {
  console.log("the document exists");
}

Exemple 3 : combinaison de styles de code avec espace de noms et modulaires

L'utilisation des bibliothèques de compatibilité lors de la mise à niveau vous permet de continuer à utiliser du code avec espace de noms en plus du code refactorisé pour l'API modulaire. Cela signifie que vous pouvez conserver le code avec espace de noms existant pour Cloud Firestore tout en refactorisant Authentication ou d'autres codes SDK Firebase au style modulaire, et compiler votre application avec les deux styles de code. Il en va de même pour le code d'API avec espace de noms et modulaire dans un produit tel que Cloud Firestore. Les styles de code nouveaux et anciens peuvent coexister, à condition que vous importiez les packages de compatibilité :

import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';
import { getDoc } from 'firebase/firestore'

const docRef = firebase.firestore().doc();
getDoc(docRef);

N'oubliez pas que, bien que votre application soit compilée, vous ne bénéficierez pas des avantages de la taille de l'application du code modulaire tant que vous n'aurez pas complètement supprimé les instructions et le code de compatibilité de votre application.

Mettre à jour le code d'initialisation

Mettez à jour le code d'initialisation de votre application pour utiliser la syntaxe modulaire. Il est important de mettre à jour ce code après avoir terminé la refactorisation de tout le code de votre application. En effet, firebase.initializeApp() initialise l'état global pour les API de compatibilité et modulaires, tandis que la fonction modulaire initializeApp() n'initialise que l'état pour le modulaire.

Avant : compat

import firebase from "firebase/compat/app"

firebase.initializeApp({ /* config */ });

Après : modulaire

import { initializeApp } from "firebase/app"

const firebaseApp = initializeApp({ /* config */ });

Supprimer le code de compatibilité

Pour bénéficier des avantages de taille de l'API modulaire, vous devez à terme convertir toutes les invocations au style modulaire présenté ci-dessus et supprimer toutes les instructions import "firebase/compat/* de votre code. Une fois terminé, il ne devrait plus y avoir de références à l'espace de noms global firebase.* ni à aucun autre code dans le style d'API avec espace de noms.

Utiliser la bibliothèque de compatibilité à partir de la fenêtre

L'API modulaire est optimisée pour fonctionner avec des modules plutôt qu'avec l'objet window du navigateur. Les versions précédentes de la bibliothèque permettaient de charger et de gérer Firebase à l'aide de l'espace de noms window.firebase. Cette approche n'est plus recommandée, car elle ne permet pas d'éliminer le code inutilisé. Toutefois, la version de compatibilité du SDK JavaScript fonctionne avec la window pour les développeurs qui préfèrent ne pas commencer immédiatement le chemin de mise à niveau modulaire.

<script src="https://www.gstatic.com/firebasejs/12.12.0/firebase-app-compa><t.js&qu>o<t;/script
script src="https://www.gstatic.com/firebasejs/12.12.0/firebase-fires><tore-co>m<pat.js"/script
script src="https://www.gstatic.com/firebasejs/12.12.0></fireba>s<e-auth>-compat.js"/script
script
   const firebaseApp = firebase.initializeApp({ /* Firebase config */ });
   const db = firebaseApp.firestore();
   con<st auth> = firebaseApp.auth();
/script

La bibliothèque de compatibilité utilise du code modulaire en arrière-plan et le fournit avec la même API que l'API avec espace de noms. Cela signifie que vous pouvez vous reporter à la documentation de référence de l'API avec espace de noms et aux extraits de code avec espace de noms pour en savoir plus. Cette méthode n'est pas recommandée pour une utilisation à long terme, mais elle constitue un bon point de départ pour passer à la bibliothèque entièrement modulaire.

Avantages et limites du SDK modulaire

Le SDK entièrement modularisé présente les avantages suivants par rapport aux versions antérieures :

  • Le SDK modulaire permet de réduire considérablement la taille de l'application. Il adopte le format de module JavaScript moderne, ce qui permet des pratiques d'élimination du code inutilisé dans lesquelles vous n'importez que les artefacts dont votre application a besoin. Selon votre application, l'élimination du code inutilisé avec le SDK modulaire peut entraîner une réduction de 80 % des kilo-octets par rapport à une application comparable créée à l'aide de l'API avec espace de noms.
  • Le SDK modulaire continuera de bénéficier du développement continu de fonctionnalités, contrairement à l'API avec espace de noms.