Le app che attualmente utilizzano qualsiasi API web Firebase con nome, dalle librerie compat
fino alla versione 8 o precedente, dovrebbero valutare la possibilità di eseguire la migrazione all'API modulare seguendo le istruzioni riportate in questa guida.
Questa guida presuppone che tu abbia dimestichezza con l'API con nome di spazio 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 aggregatore di moduli nell'ambiente di sviluppo. Se non ne utilizzi una, non potrai sfruttare i vantaggi principali dell'API modulare per ridurre le dimensioni dell'app. Per installare l'SDK, devi avere npm o yarn.
I passaggi per l'upgrade descritti in questa guida si baseranno su un'app web immaginaria che utilizza gli SDK Authentication e Cloud Firestore. Esercitandoti con gli esempi, puoi acquisire familiarità con 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
)
Esistono due tipi di librerie disponibili per l'SDK web di Firebase:
- Modulare: una nuova interfaccia API progettata per semplificare l'eliminazione di codice non utilizzato (tree-shaking) al fine di rendere la tua app web il più piccola e veloce possibile.
- Con nome (
compat
): un'interfaccia API familiare che è completamente compatibile con le versioni precedenti dell'SDK e ti consente di eseguire l'upgrade senza modificare tutto il codice Firebase contemporaneamente. Le librerie compatibili hanno pochi o nessun vantaggio in termini di dimensioni o prestazioni rispetto alle loro controparti con spazio dei nomi.
Questa guida presuppone che tu utilizzi le librerie di compatibilità per semplificare l'upgrade. Queste librerie ti consentono di continuare a utilizzare il codice con nome nello spazio dei nomi insieme al codice ristrutturato per l'API modulare. Ciò significa che puoi compilare e eseguire il debug della tua app più facilmente durante la procedura di upgrade.
Per le app con un'esposizione molto ridotta all'SDK Firebase Web, ad esempio un'app che esegue solo una semplice chiamata alle API Authentication, potrebbe essere pratico eseguire il refactoring del codice precedente con spazio dei nomi senza utilizzare le librerie compat. Se stai eseguendo l'upgrade di un'app di questo tipo, puoi seguire le istruzioni riportate in questa guida per l'"API modulare" senza utilizzare le librerie compat.
Informazioni sulla procedura di upgrade
Ogni passaggio della procedura di upgrade è definito in modo da poter completare la modifica del codice sorgente della tua app, quindi 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 compat alla tua app.
- Aggiorna le istruzioni di importazione nel codice in modo che siano compatibili.
- Esegui il refactoring del codice di un singolo prodotto (ad es. Authentication) in modo da adottare lo stile modulare.
- (Facoltativo) A questo punto, rimuovi la libreria e il codice compatibile di Authentication per Authentication per usufruire del vantaggio delle dimensioni dell'app per Authentication prima di continuare.
- Esegui il refactoring delle funzioni per ciascun prodotto (ad esempio Cloud Firestore, FCM e così via) in stile modulare, compila e testa fino a quando tutte le aree non sono complete.
- Aggiorna il codice di inizializzazione allo stile modulare.
- Rimuovi tutte le istruzioni di compatibilità e il codice di compatibilità rimanenti dalla tua app.
Scarica la versione più recente dell'SDK
Per iniziare, scarica le librerie modulari e le librerie compat utilizzando npm:
npm i firebase@11.1.0 # OR yarn add firebase@11.1.0
Aggiornare le importazioni in compat
Per mantenere il codice funzionante 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 precedente
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';
Esegui il refactoring in base allo stile modulare
Sebbene le API con spazio dei nomi siano basate su un pattern di spazio dei nomi e servizio concatenato da punti, l'approccio modulare prevede che il codice venga organizzato principalmente in base alle funzioni. Nell'API modulare, il pacchetto firebase/app
e altri pacchetti non restituiscono un'esportazione completa che contenga tutti i metodi del pacchetto. I pacchetti, invece, esportano singole funzioni.
Nell'API modulare, i servizi vengono passati come primo argomento e la funzione utilizza poi i dettagli del servizio per fare il resto. Vediamo come funziona in due esempi che eseguono il refactoring delle chiamate alle API Authentication e Cloud Firestore.
Esempio 1: refactoring di una funzione Authentication
Prima: compat
Il codice compatibile è 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: modular
La funzione getAuth
utilizza firebaseApp
come primo parametro.
La funzione onAuthStateChanged
non è collegata all'istanza auth
come accade
nella API con spazio dei nomi. È invece una funzione
libera che prende auth
come primo parametro.
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => {
// Check for user status
});
Aggiornamento della gestione del metodo di autenticazione getRedirectResult
L'API modulare introduce una modifica che comporta una interruzione 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: modular
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: modular
La funzione getFirestore
utilizza 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 è presente l'accodamento 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 incompatibile in cui la proprietà
firestore.DocumentSnapshot.exists
è stata modificata in un metodo. La funzionalità è essenzialmente la stessa (testa se esiste un documento), ma devi eseguire il refactoring del codice per utilizzare il metodo più recente, come mostrato di seguito:
Before:compat
if (snapshot.exists) {
console.log("the document exists");
}
Dopo: modular
if (snapshot.exists()) {
console.log("the document exists");
}
Esempio 3: combinazione di stili di codice con nome e modulari
L'utilizzo delle librerie compat durante l'upgrade ti consente di continuare a utilizzare il codice con nome nello spazio dei nomi insieme al codice sottoposto a refactoring per l'API modulare. Ciò significa che puoi mantenere il codice esistente con spazio dei nomi per Cloud Firestore mentre esegui il refactoring di Authentication o di altro codice dell'SDK Firebase in stile modulare e comunque compilare correttamente la tua app con entrambi gli stili di codice. Lo stesso vale per il codice API con nome e modulare all'interno di un prodotto come Cloud Firestore. I nuovi e i vecchi stili di codice possono coesistere, a condizione che tu stia importando 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, anche se l'app viene compilata, non potrai usufruire dei vantaggi relativi alle dimensioni dell'app del codice modulare finché non rimuovi completamente le istruzioni compat e il codice dalla tua app.
Aggiorna il codice di inizializzazione
Aggiorna il codice di inizializzazione dell'app in modo da utilizzare la sintassi modulare. È importante aggiornare questo codice dopo aver completato il refactoring di tutto il codice dell'app. Questo perché firebase.initializeApp()
inizializza lo stato globale sia per le API compat che per quelle modulari, mentre la funzione initializeApp()
modulare inizializza solo lo stato per le API modulari.
Prima: compat
import firebase from "firebase/compat/app"
firebase.initializeApp({ /* config */ });
Dopo: modular
import { initializeApp } from "firebase/app"
const firebaseApp = initializeApp({ /* config */ });
Rimuovere il codice di compatibilità
Per sfruttare i vantaggi in termini di dimensioni dell'API modulare, dovresti eventualmente
convertire tutte le invocazioni allo stile modulare mostrato sopra e rimuovere tutte le
dichiarazioni import "firebase/compat/*
dal codice. Al termine, non devono essere presenti riferimenti allo spazio dei nomi firebase.*
globale o ad altro codice nello stile dell'API con spazi dei nomi.
Utilizzare la libreria compat 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 opzione non è consigliata per il futuro perché 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/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>
La libreria di compatibilità utilizza codice modulare e fornisce la stessa API dell'API con nome. Ciò significa che puoi fare riferimento alla documentazione di riferimento dell'API con nome e agli snippet di codice con nome per maggiori dettagli. Questo metodo non è consigliato per l'uso a lungo termine, ma come inizio per l'upgrade alla libreria completamente modulare.
Vantaggi e limitazioni dell'SDK modulare
L'SDK completamente modularizzato presenta i seguenti vantaggi rispetto alle versioni precedenti:
- L'SDK modulare consente di ridurre notevolmente le dimensioni dell'app. Adotta il formato del modulo JavaScript moderno, consentendo pratiche di "tree shaking" in cui importi solo gli elementi necessari per la tua app. A seconda dell'app, il tree-shaking con l'SDK modulare può comportare un risparmio di 80% in termini di kilobyte rispetto a un'app simile creata utilizzando l'API con nome.
- L'SDK modulare continuerà a trarre vantaggio dallo sviluppo continuo delle funzionalità, mentre l'API con spazio dei nomi no.