Le app che utilizzano un'API web Firebase con spazio dei nomi, dalle librerie compat
fino alla versione 8 o precedenti, devono prendere in considerazione
la migrazione all'API modulare seguendo le istruzioni riportate in questa guida.
Questa guida presuppone che tu abbia familiarità con l'API con spazio dei nomi e che utilizzerai un bundler di moduli come webpack o Rollup per l'upgrade e lo sviluppo continuo di app modulari.
Ti consigliamo vivamente di utilizzare un bundler di moduli nel tuo ambiente di sviluppo. Se non ne utilizzi uno, non potrai sfruttare i principali vantaggi dell'API modulare in termini di riduzione delle dimensioni dell'app. Per installare l'SDK, devi avere npm o yarn.
I passaggi per l'upgrade descritti in questa guida si basano su un'app web immaginaria che utilizza gli SDK Authentication e Cloud Firestore. Seguendo gli esempi, puoi padroneggiare i concetti e i passaggi pratici necessari per eseguire l'upgrade di tutti gli SDK web Firebase supportati.
Informazioni sulle librerie con spazio dei nomi (compat)
Sono disponibili due tipi di librerie per l'SDK web Firebase:
- Modulare: una nuova superficie API progettata per facilitare il tree shaking (rimozione del codice inutilizzato) per rendere la tua app web il più piccola e veloce possibile.
- Con spazio dei nomi (
compat): una superficie API familiare completamente compatibile con le versioni precedenti dell'SDK, che ti consente di eseguire l'upgrade senza modificare tutto il codice Firebase contemporaneamente. Le librerie di compatibilità non offrono vantaggi significativi in termini di dimensioni o prestazioni rispetto alle loro controparti con namespace.
Questa guida presuppone che utilizzerai le librerie di compatibilità per facilitare l'upgrade. Queste librerie ti consentono di continuare a utilizzare il codice con spazi dei nomi insieme al codice rifattorizzato per l'API modulare. Ciò significa che puoi compilare ed eseguire il debug della tua app più facilmente durante il processo di upgrade.
Per le app con un'esposizione molto ridotta all'SDK web Firebase, ad esempio un'app che effettua solo una semplice chiamata alle API Authentication, potrebbe essere pratico rifattorizzare il codice con namespace precedente senza utilizzare le librerie di compatibilità. Se esegui l'upgrade di un'app di questo tipo, puoi seguire le istruzioni riportate in questa guida per "l'API modulare" senza utilizzare le librerie di compatibilità.
Informazioni sulla procedura di upgrade
Ogni passaggio del processo di upgrade è limitato in modo da consentirti di completare la modifica dell'origine dell'app, quindi di compilarla ed eseguirla senza interruzioni. In sintesi, ecco cosa devi fare per eseguire l'upgrade di un'app:
- Aggiungi le librerie modulari e le librerie di compatibilità alla tua app.
- Aggiorna le istruzioni di importazione nel codice in compat.
- Rifattorizza il codice per un singolo prodotto (ad esempio Authentication) in modo da ottenere uno stile modulare.
- (Facoltativo) A questo punto, rimuovi la libreria di compatibilità Authentication e il codice di compatibilità per Authentication per ottenere il vantaggio delle dimensioni dell'app per Authentication prima di continuare.
- Rifattorizza le funzioni per ogni prodotto (ad esempio Cloud Firestore, FCM e così via) in base allo stile modulare, compilando e testando fino a completare tutte le aree.
- Aggiorna il codice di inizializzazione allo stile modulare.
- Rimuovi tutte le istruzioni e il codice di compatibilità rimanenti dalla tua app.
Scarica l'ultima versione dell'SDK
Per iniziare, scarica le librerie modulari e le librerie di compatibilità utilizzando npm:
npm i firebase@13.2.0 # OR yarn add firebase@13.2.0
Aggiorna le importazioni in compat
Per mantenere il funzionamento del codice dopo l'aggiornamento delle dipendenze, modifica le istruzioni di importazione in modo da utilizzare la versione "compat" di ogni importazione. Ad esempio:
Prima: versione 8 o precedenti
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';
Rifattorizza allo stile modulare
Mentre le API con spazio dei nomi si basano su un pattern di servizi e spazi dei nomi concatenati con punti, l'approccio modulare prevede che il codice venga 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. I pacchetti esportano invece singole funzioni.
Nell'API modulare, i servizi vengono passati come primo argomento e la funzione utilizza i dettagli del servizio per eseguire il resto. Vediamo come funziona questo processo in due esempi che rifattorizzano le chiamate alle API Authentication e Cloud Firestore.
Esempio 1: rifattorizzazione di una funzione Authentication
Prima: compat
Il codice di compatibilità è identico al codice con spazio dei nomi, 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 all'istanza auth come sarebbe nell'API con spazio dei nomi; si tratta invece di 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 di autenticazione getRedirectResult
L'API modulare introduce una modifica che provoca un errore in getRedirectResult. Quando non viene chiamata alcuna operazione di reindirizzamento, l'API modulare restituisce null, a differenza dell'API con spazio dei nomi, che restituiva 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: rifattorizzazione 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, che è stato restituito da initializeApp in un esempio precedente. Nota come il codice per formare una query sia molto diverso nell'API modulare; non esiste 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 che provoca un errore in cui la proprietà firestore.DocumentSnapshot.exists è stata modificata in un metodo. La funzionalità è essenzialmente la stessa (verifica se un documento esiste), ma devi rifattorizzare il codice per utilizzare il metodo più recente, come mostrato:
Before: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 con namespace e modulari
L'utilizzo delle librerie di compatibilità durante l'upgrade ti consente di continuare a utilizzare il codice con spazio dei nomi insieme al codice rifattorizzato per l'API modulare. Ciò significa che puoi mantenere il codice con spazio dei nomi esistente per Cloud Firestore mentre rifattorizzi Authentication o altro codice dell'SDK Firebase nello stile modulare e continuare a compilare correttamente l'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; gli stili di codice nuovi e precedenti possono coesistere, purché importi i pacchetti compatibili:
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, anche se l'app verrà compilata, non otterrai i vantaggi in termini di dimensioni dell'app del codice modulare finché non rimuoverai completamente le istruzioni e il codice di compatibilità dall'app.
Aggiorna il codice di inizializzazione
Aggiorna il codice di inizializzazione dell'app per utilizzare la sintassi modulare. È importante aggiornare questo codice dopo aver completato il refactoring di tutto il codice nell'app, perché firebase.initializeApp() inizializza lo stato globale sia per le API compatibili che per quelle modulari, mentre la funzione modulare initializeApp() inizializza solo lo stato per le API modulari.
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 sfruttare i vantaggi in termini di dimensioni dell'API modulare, devi convertire tutte le chiamate allo stile modulare mostrato sopra e rimuovere tutte le istruzioni import "firebase/compat/* dal codice. Al termine, non dovrebbero più esserci riferimenti allo spazio dei nomi globale firebase.* o ad altro codice nello stile dell'API con spazio dei nomi.
Utilizzo della libreria di compatibilità dalla finestra
L'API modulare è ottimizzata per funzionare con i moduli anziché 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. Questa operazione non è consigliata in futuro, in quanto non consente l'eliminazione del codice inutilizzato.
Tuttavia, la versione compatibile dell'SDK JavaScript funziona con window per gli sviluppatori che preferiscono non iniziare immediatamente il percorso di upgrade modulare.
<script src="https://www.gstatic.com/firebasejs/13.2.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/13.2.0/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/13.2.0/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 un codice modulare in background e lo fornisce con 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 l'uso a lungo termine, ma come punto di partenza per l'upgrade alla libreria completamente modulare.
Vantaggi e limitazioni dell'SDK modulare
L'SDK completamente modularizzato offre i seguenti vantaggi rispetto alle versioni precedenti:
- L'SDK modulare consente di ridurre notevolmente le dimensioni dell'app. Adotta il moderno formato dei moduli JavaScript, consentendo pratiche di "tree shaking" in cui importi solo gli artefatti necessari per la tua app. A seconda dell'app, il tree shaking con l'SDK modulare può comportare una riduzione dell'80% dei kilobyte rispetto a un'app simile creata utilizzando l'API con spazio dei nomi.
- L'SDK modulare continuerà a beneficiare dello sviluppo continuo di funzionalità, mentre l'API con spazio dei nomi no.