Les applications qui utilisent actuellement 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 utiliserez un bundler de module tel que webpack ou Rollup pour la mise à niveau et le développement continu d'applications modulaires.
Nous vous recommandons vivement d'utiliser un outil de regroupement 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 réduisant la taille de l'application. Vous aurez besoin de npm ou de yarn pour installer le SDK.
Les étapes de mise à niveau de ce guide seront basées sur une application Web imaginaire qui utilise les SDK Authentication et Cloud Firestore. En suivant les exemples, vous pouvez 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:
- Modularité : nouvelle surface d'API conçue pour faciliter le tree-shaking (suppression du code inutilisé) afin de rendre votre application Web aussi petite et rapide que possible.
- Espace de noms (
compat
) : surface d'API familière, entièrement compatible avec les versions antérieures du SDK, qui vous permet de passer à la version la plus récente sans modifier l'ensemble de votre code Firebase en une seule fois. Les bibliothèques de compatibilité présentent 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 utiliserez les bibliothèques de compatibilité pour faciliter la migration. Ces bibliothèques vous permettent de continuer à utiliser du code avec un 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 au fur et à mesure du processus de mise à niveau.
Pour les applications ayant une très faible exposition 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 un 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 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:
- Ajoutez les bibliothèques modulaires et les bibliothèques de compatibilité à votre application.
- Mettez à jour les instructions d'importation de votre code pour la compatibilité.
- Refactorisez le code d'un seul produit (par exemple, Authentication) en style modulaire.
- Facultatif: à ce stade, supprimez la bibliothèque de compatibilité Authentication et le code de compatibilité pour Authentication afin de profiter de l'avantage de taille de l'application pour Authentication avant de continuer.
- Refactorisez les fonctions de chaque produit (par exemple, Cloud Firestore, FCM, etc.) en style modulaire, en compilant et en testant jusqu'à ce que toutes les zones soient terminées.
- Mettez à jour le code d'initialisation en adoptant le style modulaire.
- Supprimez toutes les instructions de compatibilité et le code de compatibilité restants de votre application.
Obtenir la dernière version du SDK
Pour commencer, récupérez les bibliothèques modulaires et les bibliothèques de compatibilité à l'aide de npm:
npm i firebase@11.1.0 # OR yarn add firebase@11.1.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 pour 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';
After: compat
// compat packages are API compatible with namespaced code
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
Refactorisation vers le style modulaire
Alors que les API avec espace de noms sont basées sur un modèle d'espace de noms et de service en chaîne de points, l'approche modulaire signifie que votre code sera organisé principalement autour de fonctions. Dans l'API modulaire, le package firebase/app
et les 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, et la fonction utilise ensuite les détails du service pour effectuer le reste. Voyons comment cela fonctionne dans deux exemples qui refactorisent les appels aux API Authentication et Cloud Firestore.
Exemple 1: Refactorisation d'une fonction Authentication
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.onAuthStateChanged(user => {
// Check for user status
});
Après: modulaire
La fonction getAuth
utilise firebaseApp
comme premier paramètre.
La fonction onAuthStateChanged
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(auth, user => {
// Check for user status
});
Mise à jour de la gestion de la méthode d'authentification getRedirectResult
L'API modulaire introduit une modification destructive dans getRedirectResult
. Lorsqu'aucune opération de redirection n'est appelée, l'API modulaire renvoie null
, contrairement à l'API associée à un 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 snapshots
console.log(doc.id, " => ", doc.data());
});
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
Après: modulaire
La fonction getFirestore
utilise 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 de chaînage, 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 getDocs(q);
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
Mise à jour des références vers DocumentSnapshot.exists
Firestore
L'API modulaire introduit une modification non rétrocompatible dans laquelle la propriété firestore.DocumentSnapshot.exists
a été remplacée par une méthode. La fonctionnalité est essentiellement la même (vérifier si un document existe), mais vous devez refactoriser votre code pour utiliser la méthode plus récente, comme indiqué:
Before:compat
if (snapshot.exists) {
console.log("the document exists");
}
Après: modulaire
if (snapshot.exists()) {
console.log("the document exists");
}
Exemple 3: Combiner des styles de code modulaire et avec espace de noms
L'utilisation des bibliothèques de compatibilité lors de la mise à niveau vous permet de continuer à utiliser du code avec un espace de noms en plus du code refactorisé pour l'API modulaire. Cela signifie que vous pouvez conserver le code existant avec un espace de noms pour Cloud Firestore pendant que vous refactorisez Authentication ou un autre code du SDK Firebase en style modulaire, et que vous pouvez toujours compiler votre application avec les deux styles de code. Il en va de même pour le code d'API modulaire et associé à un espace de noms dans un produit tel que Cloud Firestore. Les nouveaux et anciens styles de code 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, même si votre application est compilée, vous ne bénéficierez pas des avantages de taille de l'application du code modulaire tant que vous n'aurez pas complètement supprimé les instructions de compatibilité et le code de votre application.
Modifier le code d'initialisation
Mettez à jour le code d'initialisation de votre application pour qu'il utilise la syntaxe modulaire. Il est important de mettre à jour ce code après avoir terminé de refactoriser tout le code de votre application. En effet, firebase.initializeApp()
initialise l'état global à la fois pour les API de compatibilité et modulaires, tandis que la fonction initializeApp()
modulable 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 profiter des avantages de taille de l'API modulaire, vous devez à terme convertir toutes les invocations au style modulaire illustré 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é depuis 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 le chargement et la gestion de Firebase à l'aide de l'espace de noms window.firebase
. Cette approche n'est pas recommandée à l'avenir, car elle ne permet pas d'éliminer le code inutilisé.
Toutefois, la version compatible du SDK JavaScript fonctionne avec 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/11.1.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/11.1.0/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/11.1.0/firebase-auth-compat.js"></script>
<script>
const firebaseApp = firebase.initializeApp({ /* Firebase config */ });
const db = firebaseApp.firestore();
const auth = firebaseApp.auth();
</script>
Sous le capot, la bibliothèque de compatibilité utilise du code modulaire et lui fournit la même API que l'API avec espace de noms. Vous pouvez donc consulter la documentation de référence de l'API avec espace de noms et les 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 comme point de départ pour passer à la bibliothèque entièrement modulaire.
Avantages et limites du SDK modulaire
Le SDK entièrement modulaire présente les avantages suivants par rapport aux versions précédentes:
- 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 de pratiquer le "tree shaking", c'est-à-dire d'importer uniquement les artefacts dont votre application a besoin. Selon votre application, le tree-shaking avec le SDK modulaire peut réduire la taille de votre application de 80% 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 des fonctionnalités, contrairement à l'API avec espace de nommage.