Aan de slag met Cloud Firestore voor Android

Cloud Firestore is een recente toevoeging aan de Firebase-productfamilie. Hoewel het nog steeds in bèta is, wordt het al door Google gepresenteerd als een flexibeler en veelzijdig alternatief voor de Firebase Realtime-database.

Als u ooit de Realtime-database hebt gebruikt, weet u waarschijnlijk dat het in wezen een groot JSON-document is dat het meest geschikt is voor het opslaan van eenvoudige sleutel / waardeparen. Het is mogelijk om hiërarchische gegevens efficiënt en veilig op te slaan, hoewel dit mogelijk is, en het vereist een weloverwogen strategie, waarbij meestal de gegevens zo veel mogelijk worden platgedrukt of dat ze worden geneutraliseerd. Zonder een dergelijke strategie zullen queries op de Realtime-database waarschijnlijk onnodig grote hoeveelheden bandbreedte verbruiken.

Cloud Firestore, meer verwant aan document-georiënteerde databases zoals MongoDB en CouchDB, heeft zulke problemen niet. Bovendien wordt het geleverd met een groot aantal zeer handige functies, zoals ondersteuning voor batchbewerkingen, atomic writes en geïndexeerde zoekopdrachten.

In deze zelfstudie help ik u aan de slag met het gebruik van Cloud Firestore op het Android-platform.

voorwaarden

Als je deze zelfstudie wilt kunnen volgen, heb je het volgende nodig:

  • de nieuwste versie van Android Studio
  • een Firebase-account
  • en een apparaat of emulator met Android 4.4 of hoger

1. Een Firebase-project maken

Voordat u Firebase-producten in uw Android-app gebruikt, moet u hiervoor een nieuw project maken in de Firebase-console. Log hiervoor in op de console en druk op Voeg een project toe knop in het welkomstscherm.

In het dialoogvenster dat verschijnt, geeft u een betekenisvolle naam aan het project, geeft u er desgewenst een betekenisvolle ID aan en drukt u op Maak een project knop.

Nadat het project is gemaakt, kunt u Firestore als zijn database instellen door naar te navigeren Ontwikkel> Database en drukken op de Probeer Firestore Beta knop.

Zorg dat u in het volgende scherm de Start in de testmodus optie en druk op de in staat stellen knop.

Op dit moment heeft u een lege Firestore-database die klaar is om te worden gebruikt in uw app.

2. Configuratie van het Android-project

Je Android Studio-project weet nog steeds niets over het Firebase-project dat je in de vorige stap hebt gemaakt. De eenvoudigste manier om een ​​verbinding tot stand te brengen tussen beide is om de Firebase-assistent van Android Studio te gebruiken.

Ga naar Hulpmiddelen> Firebase om de assistent te openen.

Omdat Firestore nog steeds in bèta is, ondersteunt de assistent het nog niet. Desondanks kunt u, door Firebase Analytics aan uw app toe te voegen, de meeste van de vereiste configuratiestappen automatiseren.

Begin door te klikken op de Log een Analytics-evenement link onder de Analytics sectie en druk op de Maak verbinding met Firebase knop. Er zou nu een nieuw browservenster moeten verschijnen waarin u wordt gevraagd of u Android Studio toestemming wilt geven om Firebase-gegevens onder andere te beheren.

druk de Toestaan knop om door te gaan.

Terug in Android Studio, in het dialoogvenster dat verschijnt, selecteert u de Kies een bestaand Firebase- of Google-project Selecteer het Firebase-project dat u eerder hebt gemaakt en druk op Maak verbinding met Firebase knop.

Druk vervolgens op Voeg Analytics toe aan uw app om de belangrijkste Firebase-afhankelijkheden aan uw project toe te voegen.

Ten slotte, om Firestore toe te voegen als een implementatie afhankelijkheid, voeg de volgende regel toe in de app module build.gradle het dossier:

implementatie 'com.google.firebase: firebase-firestore: 11.8.0'

Vergeet niet op te drukken Synchroniseer nu om de configuratie te voltooien. Als er fouten in versieconflict optreden tijdens het synchronisatieproces, controleer dan of de versies van de Firestore-afhankelijkheid en de Firebase Core-afhankelijkheid identiek zijn en probeer het opnieuw.

3. Documenten en verzamelingen begrijpen

Firestore is een NoSQL-database waarmee u gegevens kunt opslaan in de vorm van JSON-achtige documenten. Een document dat erop is opgeslagen, kan echter niet onafhankelijk bestaan. Het moet altijd tot een verzameling behoren. Zoals de naam al doet vermoeden, is een verzameling niets anders dan een heleboel documenten. 

Documenten binnen een verzameling zijn uiteraard broers en zussen. Als u echter ouder-kindrelaties wilt leggen, moet u subcollecties gebruiken. Een subcollectie is slechts een verzameling die bij een document hoort. Standaard wordt een document automatisch het bovenliggende element van alle documenten die tot zijn subcollecties behoren.

Het is ook vermeldenswaard dat Firestore de creatie en verwijdering van beide collecties en subcollecties zelf regelt. Wanneer u een document probeert toe te voegen aan een niet-bestaande verzameling, wordt de verzameling gemaakt. Als u alle documenten uit een verzameling verwijdert, wordt deze ook verwijderd.

4. Documenten maken

Om vanuit uw Android-app naar de Firestore-database te kunnen schrijven, moet u eerst een verwijzing ernaar krijgen door het getInstance () methode van de FirebaseFirestore klasse.

val myDB = FirebaseFirestore.getInstance ()

Vervolgens moet u een nieuwe verzameling maken of een verwijzing naar een bestaande verzameling krijgen door de verzameling() methode. In een lege database maakt de volgende code bijvoorbeeld een nieuwe verzameling met de naam zonnestelsel:

val solarSystem = myDB.collection ("solar_system")

Zodra u een verwijzing naar een verzameling hebt, kunt u beginnen met het toevoegen van documenten door ernaar te bellen toevoegen() methode, die een kaart als argument verwacht.

// Voeg een document toe solarSystem.add (mapOf ("name" in "Mercury", "number" to 1, "gravity" to 3.7)) // Voeg nog een document solarSystem.add toe (mapOf ("name" to "Venus") , "nummer" tot 2, "zwaartekracht" tot 8,87))

De toevoegen() methode genereert en wijst automatisch een uniek alfanumeriek ID toe aan elk document dat wordt gemaakt. Als u wilt dat uw documenten in plaats daarvan uw eigen aangepaste ID's hebben, moet u deze documenten eerst handmatig maken door het te gebruiken document() methode, die een unieke ID-reeks als invoer gebruikt. U kunt de documenten vervolgens invullen door de set () methode, die, net als de toevoegen methode, verwacht een kaart als het enige argument.

Met de volgende code wordt bijvoorbeeld een nieuw document gemaakt en gevuld dat wordt genoemd PLANEET AARDE:

solarSystem.document ("PLANET_EARTH") .set (mapOf ("name" in "Earth", "number" to 3, "gravity" to 9.807))

Als u naar de Firebase-console gaat en de inhoud van de database bekijkt, kunt u gemakkelijk de aangepaste ID herkennen.

Let op dat als de aangepaste ID die u doorgeeft aan de document() methode bestaat al in de database, de set () methode overschrijft de inhoud van het bijbehorende document.

5. Subcollecties creëren

Ondersteuning voor subcollecties is een van de krachtigste functies van Firestore en maakt het duidelijk anders dan de Firebase Realtime-database. Door deelcollecties te gebruiken, kunt u niet alleen eenvoudig geneste structuren aan uw gegevens toevoegen, maar bent u er ook zeker van dat uw zoekopdrachten minimale hoeveelheden bandbreedte zullen verbruiken.

Een subcollectie maken lijkt veel op het maken van een verzameling. Het enige wat u hoeft te doen is bellen met de verzameling() methode op a DocumentReference object en geef een string door, die zal worden gebruikt als de naam van de subcollectie.

De volgende code maakt bijvoorbeeld een subcollectie genaamd satellieten en associeert het met de PLANEET AARDE document:

val satellitesOfEarth = solarSystem.document ("PLANET_EARTH") .collection ("satellites")

Zodra u een verwijzing naar een deelcollectie hebt, kunt u de toevoegen() of set () methoden om documenten aan toe te voegen.

satellitesOfEarth.add (mapOf ("name" in "The Moon", "gravity" into 1.62, "radius" to 1738))

Nadat u de bovenstaande code hebt uitgevoerd, wordt de PLANEET AARDE document ziet er als volgt uit in de Firebase-console:

6. Uitvoeren van query's

Het uitvoeren van een leesbewerking op uw Firestore-database is heel eenvoudig als u de ID kent van het document dat u wilt lezen. Waarom? Omdat u direct een verwijzing naar het document kunt krijgen door het verzameling() en document() methoden. Hier is bijvoorbeeld hoe u een verwijzing naar de kunt krijgen PLANEET AARDE document dat bij de. behoort zonnestelsel verzameling:

val planetEarthDoc = myDB.collection ("solar_system") .document ("PLANET_EARTH")

Om de inhoud van het document daadwerkelijk te kunnen lezen, moet u asynchroon bellen krijgen() methode, die a retourneert Taak. Door een toe te voegen OnSuccessListener erop kunt u een melding krijgen wanneer de leesbewerking met succes is voltooid.

Het resultaat van een leesbewerking is een DocumentSnapshot object, dat de sleutel / waarde-paren bevat die in het document aanwezig zijn. Door zijn krijgen() methode, kunt u de waarde van elke geldige sleutel krijgen. Het volgende voorbeeld laat zien hoe:

planetEarthDoc.get (). addOnSuccessListener println ("Zwaartekracht van $ it.get (" name ") is $ it.get (" gravity ") m / s / s") // OUTPUT: // De zwaartekracht van de aarde is 9.807 m / s / s

Als u de ID van het document dat u wilt lezen niet kent, moet u een traditionele query uitvoeren op een hele verzameling. De firestore-API biedt intuïtief genoemde filtermethoden, zoals whereEqualTo ()whereLessThan (), en whereGreaterThan (). Omdat de filtermethoden meerdere documenten als hun resultaten kunnen retourneren, hebt u een lus nodig in uw OnSuccessListener om elk resultaat af te handelen.

Als u bijvoorbeeld de inhoud van het document voor planeet Venus wilt ophalen, die we in een eerdere stap hebben toegevoegd, kunt u de volgende code gebruiken:

myDB.collection ("solar_system") .whereEqualTo ("name", "Venus") .get (). addOnSuccessListener it.forEach println ("Gravity of $ it.get (" name ") is $ it .get ("zwaartekracht") m / s / s ") // OUTPUT: // De zwaartekracht van Venus is 8,87 m / s / s

Ten slotte kunt u, als u geïnteresseerd bent in het lezen van alle documenten die tot een verzameling behoren, direct het krijgen() methode voor de verzameling. Hier is bijvoorbeeld hoe je alle planeten kunt weergeven die aanwezig zijn in de zonnestelsel verzameling:

myDB.collection ("solar_system") .get (). addOnSuccessListener it.forEach println (it.get ("name")) // OUTPUT: // Earth // Venus // Mercury

Merk op dat er standaard geen definitieve volgorde is waarin de resultaten worden geretourneerd. Als u ze wilt bestellen op basis van een sleutel die in alle resultaten aanwezig is, kunt u gebruik maken van de orderBy () methode. De volgende code bestelt de resultaten op basis van de waarde van de aantal sleutel:

myDB.collection ("solar_system") .orderBy ("number") .get (). addOnSuccessListener it.forEach println (it.get ("name")) // OUTPUT: // Mercury // Venus / / Aarde

7. Gegevens verwijderen

Als u een document met een bekende ID wilt verwijderen, hoeft u alleen maar een verwijzing ernaar te krijgen en vervolgens de. Te bellen wissen () methode.

myDB.collection ("solar_system") .document ("PLANET_EARTH") .delete ()

Het verwijderen van meerdere documenten, documenten die u krijgt als resultaat van een zoekopdracht, is iets gecompliceerder omdat hiervoor geen ingebouwde methode bestaat. Er zijn twee verschillende benaderingen die u kunt volgen.

De eenvoudigste en meest intuïtieve benadering - hoewel een die slechts geschikt is voor een zeer klein aantal documenten - is om door de resultaten te bladeren, een verwijzing naar elk document te krijgen en vervolgens de wissen () methode. Hier leest u hoe u de methode kunt gebruiken om alle documenten in de map te verwijderen zonnestelsel verzameling:

myDB.collection ("solar_system") .get (). addOnSuccessListener it.forEach it.reference.delete ()

Een efficiëntere en schaalbare aanpak is om een ​​batch-bewerking te gebruiken. Batchbewerkingen kunnen niet alleen meerdere documenten atomisch verwijderen, maar ook het aantal vereiste netwerkverbindingen aanzienlijk verminderen.

Om een ​​nieuwe batch te maken, moet u de partij() methode van uw database, die een exemplaar van de WriteBatch klasse. Vervolgens kunt u alle resultaten van de query doorlopen en markeren voor verwijdering door ze door te geven aan de wissen () methode van de WriteBatch voorwerp. Tot slot, om het verwijderingsproces daadwerkelijk te starten, kunt u bellen met commit () methode. De volgende code laat zien hoe:

myDB.collection ("solar_system") .get (). addOnSuccessListener // Maak batch val myBatch = myDB.batch () // Voeg documenten toe aan batch it.forEach myBatch.delete (it.reference) // Run batch myBatch.commit ()

Merk op dat wanneer u probeert om te veel documenten toe te voegen aan een enkele batchbewerking, dit kan leiden tot onvoldoende geheugen. Als u daarom waarschijnlijk een groot aantal documenten retourneert, moet u ervoor zorgen dat u ze in meerdere batches splitst

Conclusie

In deze inleidende zelfstudie hebt u geleerd hoe u lees- en schrijfbewerkingen in de Google Cloud Firestore kunt uitvoeren. Ik stel voor dat je het meteen gaat gebruiken in je Android-projecten. De kans is groot dat het in de toekomst de Realtime-database zal vervangen. In feite zegt Google al dat tegen de tijd dat het uit de bèta komt, het veel betrouwbaarder en schaalbaarder zal zijn dan de Realtime Database.

Voor meer informatie over Cloud Firestore kunt u de officiële documentatie raadplegen.

En terwijl je hier bent, bekijk enkele van onze andere tutorials over de ontwikkeling van Firebase en Android-apps!