Le app che attualmente utilizzano qualsiasi API Web Firebase con spazio dei nomi, dalle librerie compat
fino alla versione 8 o precedente, dovrebbero prendere in considerazione la migrazione all'API modulare utilizzando le istruzioni in questa guida.
Questa guida presuppone che tu abbia familiarità con l'API con spazio dei nomi e che trarrai vantaggio da un bundler di moduli come Webpack o Rollup per l'aggiornamento e lo sviluppo continuo di app modulari.
Si consiglia vivamente di utilizzare un bundler di moduli nel proprio ambiente di sviluppo. Se non ne usi uno, non sarai in grado di sfruttare i principali vantaggi dell'API modulare nella dimensione ridotta dell'app. Avrai bisogno di npm o yarn per installare l'SDK.
I passaggi di aggiornamento in questa guida si baseranno su un'app Web immaginaria che utilizza gli SDK di autenticazione e Cloud Firestore. Analizzando gli esempi, puoi padroneggiare i concetti e i passaggi pratici necessari per eseguire l'upgrade di tutti gli SDK Web di Firebase supportati.
Informazioni sulle librerie namespace ( compat
).
Sono disponibili due tipi di librerie per Firebase Web SDK:
- Modulare : una nuova superficie API progettata per facilitare lo scuotimento dell'albero (rimozione del codice inutilizzato) per rendere la tua app Web il più piccola e veloce possibile.
- Namespaced (
compat
) : una superficie API familiare completamente compatibile con le versioni precedenti dell'SDK, che consente di eseguire l'aggiornamento senza modificare tutto il codice Firebase in una volta. Le librerie Compat hanno pochi o nessun vantaggio in termini di dimensioni o prestazioni rispetto alle loro controparti con spazio dei nomi.
Questa guida presuppone che sfrutterai le librerie compat per facilitare il tuo aggiornamento. Queste librerie ti consentono di continuare a utilizzare il codice con spazio dei nomi insieme al codice sottoposto a refactoring per l'API modulare. Ciò significa che puoi compilare ed eseguire il debug della tua app più facilmente durante il processo di aggiornamento.
Per le app con un'esposizione molto ridotta a Firebase Web SDK, ad esempio un'app che effettua solo una semplice chiamata alle API di autenticazione, potrebbe essere pratico eseguire il refactoring del codice con spazio dei nomi precedente senza utilizzare le librerie di compatibilità. Se stai aggiornando un'app di questo tipo, puoi seguire le istruzioni in questa guida per "l'API modulare" senza utilizzare le librerie compat.
Informazioni sul processo di aggiornamento
Ogni fase del processo di aggiornamento ha un ambito in modo che tu possa completare la modifica del codice sorgente per la tua app e quindi compilarla ed eseguirla senza problemi. In sintesi, ecco cosa devi fare per aggiornare un'app:
- Aggiungi le librerie modulari e le librerie compat alla tua app.
- Aggiorna le dichiarazioni di importazione nel tuo codice per compat.
- Refactoring del codice per un singolo prodotto (ad esempio, Autenticazione) nello stile modulare.
- Facoltativo: a questo punto, rimuovi la libreria di compatibilità di autenticazione e il codice di compatibilità per l'autenticazione per realizzare il vantaggio delle dimensioni dell'app per l'autenticazione prima di continuare.
- Funzioni di refactoring per ogni prodotto (ad esempio, Cloud Firestore, FCM, ecc.) in stile modulare, compilazione e test fino al completamento di tutte le aree.
- Aggiorna il codice di inizializzazione allo stile modulare.
- Rimuovi dall'app tutte le dichiarazioni compat rimanenti e il codice compat.
Scarica l'ultima versione dell'SDK
Per iniziare, scarica le librerie modulari e le librerie compat usando npm:
npm i firebase@10.3.1 # OR yarn add firebase@10.3.1
Aggiorna le importazioni a compat
Per mantenere il codice funzionante dopo aver aggiornato le dipendenze, modifica le istruzioni di importazione in modo che utilizzino la versione "compat" di ciascuna importazione. Per esempio:
Prima: versione 8 o precedente
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
Dopo: compat
// compat packages are API compatible with namespaced code
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
Refactor allo stile modulare
Mentre le API con spazio dei nomi si basano su uno spazio dei nomi e un modello di servizio concatenati a punti, l'approccio modulare significa che il tuo codice sarà organizzato principalmente attorno alle funzioni . Nell'API modulare, il pacchetto firebase/app
e altri pacchetti non restituiscono un'esportazione completa che contiene tutti i metodi del pacchetto. Invece, i pacchetti esportano singole funzioni.
Nell'API modulare, i servizi vengono passati come primo argomento e la funzione utilizza quindi i dettagli del servizio per fare il resto. Esaminiamo come funziona in due esempi che effettuano il refactoring delle chiamate alle API di autenticazione e Cloud Firestore.
Esempio 1: refactoring di una funzione di autenticazione
Prima: compat
Il codice compat è identico al codice namespace, ma le importazioni sono cambiate.
import firebase from "firebase/compat/app";
import "firebase/compat/auth";
const auth = firebase.auth();
auth.onAuthStateChanged(user => {
// Check for user status
});
Dopo: modulare
La funzione getAuth
accetta firebaseApp
come primo parametro. La funzione onAuthStateChanged
non è concatenata dall'istanza auth
come sarebbe nell'API con spazio dei nomi; invece, è una funzione libera che accetta auth
come primo parametro.
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => {
// Check for user status
});
Aggiorna la gestione del metodo Auth getRedirectResult
L'API modulare introduce una modifica sostanziale in getRedirectResult
. Quando non viene chiamata alcuna operazione di reindirizzamento, l'API modulare restituisce null
in contrasto con l'API con spazio dei nomi, che ha restituito un UserCredential
con un utente null
.
Prima: compat
const result = await auth.getRedirectResult()
if (result.user === null && result.credential === null) {
return null;
}
return result;
Dopo: modulare
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;
Esempio 2: refactoring di una funzione Cloud Firestore
Prima: 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);
});
Dopo: modulare
La funzione getFirestore
accetta firebaseApp
come primo parametro, restituito da initializeApp
in un esempio precedente. Nota come il codice per formare una query è molto diverso nell'API modulare; non c'è concatenamento e metodi come query
o where
sono ora esposti come funzioni libere.
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());
});
Aggiorna i riferimenti a Firestore DocumentSnapshot.exists
L'API modulare introduce una modifica sostanziale in cui la proprietà firestore.DocumentSnapshot.exists
è stata modificata in un metodo . La funzionalità è essenzialmente la stessa (verifica dell'esistenza di un documento) ma è necessario eseguire il refactoring del codice per utilizzare il metodo più recente come mostrato:
Prima: compat
if (snapshot.exists) {
console.log("the document exists");
}
Dopo: modulare
if (snapshot.exists()) {
console.log("the document exists");
}
Esempio 3: combinazione di stili di codice namespace e modulari
L'utilizzo delle librerie compat durante l'aggiornamento consente di continuare a utilizzare il codice con spazio dei nomi insieme al codice sottoposto a refactoring per l'API modulare. Ciò significa che puoi mantenere il codice con spazio dei nomi esistente per Cloud Firestore mentre esegui il refactoring dell'autenticazione o altro codice dell'SDK Firebase nello stile modulare e comunque compilare correttamente la tua app con entrambi gli stili di codice. Lo stesso vale per il codice API con spazio dei nomi e modulare all'interno di un prodotto come Cloud Firestore; nuovi e vecchi stili di codice possono coesistere, purché importi i pacchetti compat:
import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';
import { getDoc } from 'firebase/firestore'
const docRef = firebase.firestore().doc();
getDoc(docRef);
Tieni presente che, sebbene la tua app venga compilata, non otterrai i vantaggi delle dimensioni dell'app del codice modulare fino a quando non rimuoverai completamente le istruzioni e il codice compat dalla tua app.
Aggiorna il codice di inizializzazione
Aggiorna il codice di inizializzazione della tua app per utilizzare la sintassi modulare. È importante aggiornare questo codice dopo aver completato il refactoring di tutto il codice nella tua app; questo perché firebase.initializeApp()
inizializza lo stato globale per entrambe le API compat e modular, mentre la funzione modular initializeApp()
inizializza solo lo stato per modular.
Prima: compat
import firebase from "firebase/compat/app"
firebase.initializeApp({ /* config */ });
Dopo: modulare
import { initializeApp } from "firebase/app"
const firebaseApp = initializeApp({ /* config */ });
Rimuovi il codice di compatibilità
Per realizzare i vantaggi in termini di dimensioni dell'API modulare, dovresti eventualmente convertire tutte le invocazioni nello stile modulare mostrato sopra e rimuovere tutte le istruzioni import "firebase/compat/*
dal tuo codice. Quando hai finito, non dovrebbero esserci più riferimenti allo spazio dei nomi globale firebase.*
o qualsiasi altro codice nello stile dell'API con spazio dei nomi.
Utilizzando la libreria compat dalla finestra
L'API modulare è ottimizzata per funzionare con i moduli piuttosto che con l'oggetto window
del browser. Le versioni precedenti della libreria consentivano il caricamento e la gestione di Firebase utilizzando lo spazio dei nomi window.firebase
. Questo non è raccomandato in futuro poiché non consente l'eliminazione del codice inutilizzato. Tuttavia, la versione compatibile dell'SDK JavaScript funziona con la window
per gli sviluppatori che preferiscono non iniziare immediatamente il percorso di aggiornamento modulare.
<script src="https://www.gstatic.com/firebasejs/10.3.1/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/10.3.1/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/10.3.1/firebase-auth-compat.js"></script>
<script>
const firebaseApp = firebase.initializeApp({ /* Firebase config */ });
const db = firebaseApp.firestore();
const auth = firebaseApp.auth();
</script>
La libreria di compatibilità utilizza il codice modulare sotto il cofano e gli fornisce la stessa API dell'API con spazio dei nomi; ciò significa che puoi fare riferimento al riferimento API con spazio dei nomi e agli snippet di codice con spazio dei nomi per i dettagli. Questo metodo non è consigliato per un uso a lungo termine, ma come inizio per l'aggiornamento alla libreria completamente modulare.
Vantaggi e limiti dell'SDK modulare
L'SDK completamente modulare presenta questi vantaggi rispetto alle versioni precedenti:
- L'SDK modulare consente di ridurre notevolmente le dimensioni dell'app. Adotta il moderno formato del modulo JavaScript, consentendo pratiche di "scuotimento dell'albero" in cui importi solo gli artefatti necessari alla tua app. A seconda della tua app, lo scuotimento dell'albero con l'SDK modulare può comportare l'80% in meno di kilobyte rispetto a un'app comparabile creata utilizzando l'API con spazio dei nomi.
- L'SDK modulare continuerà a beneficiare dello sviluppo continuo delle funzionalità, mentre l'API con spazio dei nomi no.