Cloud Firestore è una recente aggiunta alla famiglia di prodotti Firebase. Sebbene sia ancora in versione beta, è già stato presentato da Google come alternativa più flessibile e ricca di funzionalità al database in tempo reale di Firebase.
Se hai mai usato il Realtime Database, probabilmente sei consapevole del fatto che si tratta essenzialmente di un documento JSON di grandi dimensioni, più adatto per archiviare solo coppie chiave-valore. Conservare i dati gerarchici su di essa in modo efficiente e sicuro, anche se possibile, è piuttosto macchinoso e richiede una strategia ben ponderata, che di solito comporta l'appiattimento dei dati il più possibile o la denormalizzazione. Senza una tale strategia, le query sul Realtime Database potrebbero consumare quantità eccessive di larghezza di banda inutilmente.
Cloud Firestore, essendo più simile ai database orientati ai documenti come MongoDB e CouchDB, non presenta tali problemi. Inoltre, viene fornito con un gran numero di funzionalità molto utili, come il supporto per le operazioni batch, le scritture atomiche e le query indicizzate.
In questo tutorial, ti aiuterò a iniziare a utilizzare Cloud Firestore sulla piattaforma Android.
Per poter seguire questo tutorial, avrai bisogno di:
Prima di utilizzare i prodotti Firebase nella tua app Android, devi creare un nuovo progetto per questo nella console Firebase. Per fare ciò, accedere alla console e premere il tasto Aggiungi progetto pulsante nella schermata di benvenuto.
Nella finestra di dialogo che si apre, dare un nome significativo al progetto, facoltativamente dare un ID significativo ad esso, e premere il tasto Crea progetto pulsante.
Una volta che il progetto è stato creato, puoi impostare Firestore come suo database navigando Sviluppa> Database e premendo il tasto Prova Firestore Beta pulsante.
Nella schermata successiva, assicurati di scegliere il Inizia in modalità test opzione e premere il tasto Abilitare pulsante.
A questo punto, avrai un database Firestore vuoto pronto per essere utilizzato nella tua app.
Il tuo progetto Android Studio non sa ancora nulla del progetto Firebase che hai creato nel passaggio precedente. Il modo più semplice per stabilire una connessione tra i due è utilizzare l'Assistente Firebase di Android Studio.
Vai a Strumenti> Firebase per aprire l'Assistente.
Poiché Firestore è ancora in beta, l'Assistente non lo supporta ancora. Tuttavia, aggiungendo Firebase Analytics alla tua app, sarai in grado di automatizzare la maggior parte dei passaggi di configurazione richiesti.
Inizia facendo clic sul Registra un evento di Analytics collegamento sotto il analitica sezione e premendo il tasto Connetti a Firebase pulsante. Ora dovrebbe apparire una nuova finestra del browser che ti chiede se vuoi consentire ad Android Studio di gestire, tra le altre cose, i dati di Firebase.
premi il permettere pulsante per continuare.
Di nuovo in Android Studio, nella finestra di dialogo che si apre, seleziona il Scegli un progetto Firebase o Google esistente opzione, scegli il progetto Firebase creato in precedenza e premi il tasto Connetti a Firebase pulsante.
Quindi, premere il tasto Aggiungi Analytics alla tua app pulsante per aggiungere le dipendenze core di Firebase al progetto.
Infine, per aggiungere Firestore come un implementazione
dipendenza, aggiungere la seguente riga in App
modulo di build.gradle file:
implementazione 'com.google.firebase: firebase-firestore: 11.8.0'
Non dimenticare di premere il tasto Sincronizza ora pulsante per completare la configurazione. Se si verificano errori di conflitto di versione durante il processo di sincronizzazione, assicurarsi che le versioni della dipendenza Firestore e della dipendenza Firebase Core siano identiche e riprovare.
Firestore è un database NoSQL che consente di archiviare dati sotto forma di documenti simili a JSON. Tuttavia, un documento memorizzato su di esso non può esistere indipendentemente. Deve sempre appartenere a una collezione. Come suggerisce il nome, una collezione non è altro che un mucchio di documenti.
I documenti all'interno di una collezione sono ovviamente fratelli. Se si desidera stabilire relazioni parent-child tra di loro, tuttavia, è necessario utilizzare le sottoraccolte. Una sottoraccolta è solo una raccolta che appartiene a un documento. Per impostazione predefinita, un documento diventa automaticamente il genitore di tutti i documenti che appartengono alla sua sottoraccolta.
Vale anche la pena notare che Firestore gestisce da solo la creazione e l'eliminazione di collezioni e sottoraccolte. Ogni volta che provi ad aggiungere un documento a una raccolta inesistente, crea la raccolta. Allo stesso modo, una volta eliminati tutti i documenti da una raccolta, la elimina.
Per poter scrivere sul database Firestore dalla tua app Android, devi prima ottenere un riferimento ad esso chiamando il getInstance ()
metodo del FirebaseFirestore
classe.
val myDB = FirebaseFirestore.getInstance ()
Successivamente, è necessario creare una nuova raccolta o ottenere un riferimento a una raccolta esistente, chiamando il collezione()
metodo. Ad esempio, su un database vuoto, il codice seguente crea una nuova raccolta denominata sistema solare
:
val solarSystem = myDB.collection ("solar_system")
Una volta che hai un riferimento a una raccolta, puoi iniziare ad aggiungere documenti ad essa chiamando il suo Inserisci()
metodo, che si aspetta una mappa come argomento.
// Aggiungi un documento solarSystem.add (mapOf ("nome" a "Mercury", "numero" a 1, "gravità" a 3.7)) // Aggiungi un altro documento solarSystem.add (mapOf ("name" a "Venus" , "numero" a 2, "gravità" a 8.87))
Il Inserisci()
il metodo genera e assegna automaticamente un identificatore alfanumerico univoco a ogni documento creato. Se invece desideri che i tuoi documenti abbiano i tuoi ID personalizzati, devi prima creare manualmente quei documenti chiamando il documento()
metodo, che accetta come input una stringa ID univoca. È quindi possibile popolare i documenti chiamando il impostato()
metodo, che, come il Inserisci
metodo, si aspetta una mappa come unico argomento.
Ad esempio, il codice seguente crea e popola un nuovo documento chiamato PIANETA TERRA
:
solarSystem.document ("PLANET_EARTH") .set (mapOf ("nome" a "Terra", "numero" a 3, "gravità" a 9.807))
Se vai alla console di Firebase e dai un'occhiata al contenuto del database, sarai in grado di individuare facilmente l'ID personalizzato.
Attenzione che se l'ID personalizzato si passa al documento()
il metodo esiste già nel database, il impostato()
il metodo sovrascriverà il contenuto del documento associato.
Il supporto per le sottoraccolte è una delle funzionalità più potenti di Firestore ed è ciò che lo rende notevolmente diverso dal Database in tempo reale di Firebase. Usando le sottoraccolte, non solo puoi facilmente aggiungere strutture nidificate ai tuoi dati, ma assicurati anche che le tue query consumino quantità minime di larghezza di banda.
La creazione di una sottoraccolta è simile alla creazione di una raccolta. Tutto quello che devi fare è chiamare il collezione()
metodo su a DocumentReference
oggetto e passare una stringa ad esso, che verrà utilizzato come nome della sottoraccolta.
Ad esempio, il codice seguente crea una sottoraccolta chiamata satelliti
e lo associa al PIANETA TERRA
documento:
val satellitesOfEarth = solarSystem.document ("PLANET_EARTH") .collection ("satellites")
Una volta che hai un riferimento a una sottoraccolta, sei libero di chiamare il Inserisci()
o impostato()
metodi per aggiungere documenti ad esso.
satellitesOfEarth.add (mapOf ("name" in "The Moon", "gravity" in 1.62, "radius" in 1738))
Dopo aver eseguito il codice sopra, il PIANETA TERRA
il documento sarà simile alla console Firebase:
L'esecuzione di un'operazione di lettura sul database Firestore è molto semplice se si conosce l'ID del documento che si desidera leggere. Perché? Perché puoi ottenere direttamente un riferimento al documento chiamando il collezione()
e documento()
metodi. Ad esempio, ecco come ottenere un riferimento a PIANETA TERRA
documento che appartiene al sistema solare
collezione:
val planetEarthDoc = myDB.collection ("solar_system") .document ("PLANET_EARTH")
Per leggere effettivamente il contenuto del documento, è necessario chiamare asincrono ottenere()
metodo, che restituisce a Compito
. Aggiungendo un OnSuccessListener
ad esso, puoi essere avvisato quando l'operazione di lettura si completa con successo.
Il risultato di un'operazione di lettura è a DocumentSnapshot
oggetto, che contiene le coppie chiave-valore presenti nel documento. Usando il suo ottenere()
metodo, è possibile ottenere il valore di qualsiasi chiave valida. Il seguente esempio mostra come:
planetEarthDoc.get (). addOnSuccessListener println ("La gravità di $ it.get (" nome ") è $ it.get (" gravità ") m / s / s") // OUTPUT: // Gravità della Terra è 9.807 m / s / s
Se non si conosce l'ID del documento che si desidera leggere, sarà necessario eseguire una query tradizionale su un'intera raccolta. L'API Firestore fornisce metodi di filtro con nome intuitivo come whereEqualTo ()
, whereLessThan ()
, e whereGreaterThan ()
. Poiché i metodi di filtro possono restituire più documenti come risultati, è necessario un ciclo all'interno del tuo OnSuccessListener
per gestire ogni risultato.
Ad esempio, per ottenere il contenuto del documento per il pianeta Venere, che abbiamo aggiunto in una fase precedente, è possibile utilizzare il seguente codice:
myDB.collection ("solar_system") .whereEqualTo ("name", "Venus") .get (). addOnSuccessListener it.forEach println ("La gravità di $ it.get (" nome ") è $ it .get ("gravità") m / s / s ") // OUTPUT: // Gravity of Venus è 8.87 m / s / s
Infine, se sei interessato a leggere tutti i documenti che appartengono a una collezione, puoi chiamare direttamente il ottenere()
metodo sulla raccolta. Ad esempio, ecco come è possibile elencare tutti i pianeti presenti nel sistema solare
collezione:
myDB.collection ("solar_system") .get (). addOnSuccessListener it.forEach println (it.get ("nome")) // OUTPUT: // Terra // Venus // Mercury
Si noti che, per impostazione predefinita, non esiste un ordine definito in cui vengono restituiti i risultati. Se si desidera ordinarli in base a una chiave presente in tutti i risultati, è possibile utilizzare ordinato da()
metodo. Il seguente codice ordina i risultati in base al valore di numero
chiave:
myDB.collection ("solar_system") .orderBy ("number") .get (). addOnSuccessListener it.forEach println (it.get ("nome")) // OUTPUT: // Mercury // Venus / / Terra
Per eliminare un documento con un ID noto, tutto ciò che devi fare è ottenere un riferimento e quindi chiamare il Elimina()
metodo.
myDB.collection ("solar_system") .document ("PLANET_EARTH") .delete ()
L'eliminazione di più documenti, ovvero i documenti ottenuti come risultato di una query, è leggermente più complicata perché non esiste un metodo incorporato per farlo. Ci sono due diversi approcci che puoi seguire.
L'approccio più semplice e intuitivo, sebbene sia adatto solo per un numero molto limitato di documenti, consiste nel passare in rassegna i risultati, ottenere un riferimento a ciascun documento e quindi chiamare il Elimina()
metodo. Ecco come è possibile utilizzare l'approccio per eliminare tutti i documenti in sistema solare
collezione:
myDB.collection ("solar_system") .get (). addOnSuccessListener it.forEach it.reference.delete ()
Un approccio più efficiente e scalabile consiste nell'utilizzare un'operazione batch. Le operazioni batch possono non solo eliminare più documenti in modo atomico ma anche ridurre significativamente il numero di connessioni di rete richieste.
Per creare un nuovo batch, è necessario chiamare il batch ()
metodo del tuo database, che restituisce un'istanza del WriteBatch
classe. Quindi, puoi scorrere tutti i risultati della query e contrassegnarli per l'eliminazione passandoli a Elimina()
metodo del WriteBatch
oggetto. Infine, per avviare effettivamente il processo di cancellazione, è possibile chiamare il commettere()
metodo. Il seguente codice mostra come:
myDB.collection ("solar_system") .get (). addOnSuccessListener // Crea batch val myBatch = myDB.batch () // Aggiungi i documenti a batch it.forEach myBatch.delete (it.reference) // Esegui batch myBatch.commit ()
Si noti che il tentativo di aggiungere troppi documenti a una singola operazione batch può portare a errori di memoria insufficiente. Pertanto, se è probabile che la query restituisca un numero elevato di documenti, è necessario assicurarsi di dividerli in più lotti
In questo tutorial introduttivo, hai imparato come eseguire operazioni di lettura e scrittura su Google Cloud Firestore. Ti suggerisco di iniziare a utilizzarlo nei tuoi progetti Android subito. Ci sono buone probabilità che sostituirà il database Realtime in futuro. Infatti, Google dice già che quando uscirà dalla beta, sarà molto più affidabile e scalabile rispetto al database Realtime.
Per saperne di più su Cloud Firestore, puoi fare riferimento alla sua documentazione ufficiale.
E mentre sei qui, dai un'occhiata ad alcuni dei nostri altri tutorial su Firebase e lo sviluppo di app per Android!