Démarrer avec Cloud Firestore pour Android

Cloud Firestore est un ajout récent à la famille de produits Firebase. Bien que toujours en version bêta, Google le présente déjà comme une alternative plus flexible et plus riche en fonctionnalités à la base de données en temps réel Firebase..

Si vous avez déjà utilisé la base de données Realtime, vous savez probablement qu'il s'agit essentiellement d'un document JSON volumineux, parfaitement adapté au stockage de paires clé-valeur simples. Stocker des données hiérarchiques sur ces données de manière efficace et sécurisée, bien que possible, est assez fastidieux et nécessite une stratégie bien pensée, qui consiste généralement à aplatir autant que possible les données ou à les dénormaliser. Sans cette stratégie, les requêtes sur la base de données Realtime risquent de consommer inutilement de grandes quantités de bande passante..

Cloud Firestore, s'apparentant davantage à des bases de données orientées documents telles que MongoDB et CouchDB, ne pose pas de tels problèmes. De plus, il comporte un grand nombre de fonctionnalités très pratiques, telles que la prise en charge des opérations par lots, des écritures atomiques et des requêtes indexées..

Dans ce tutoriel, je vais vous aider à utiliser Cloud Firestore sur la plate-forme Android..

Conditions préalables

Pour pouvoir suivre ce tutoriel, vous aurez besoin de:

  • la dernière version d'Android Studio
  • un compte Firebase
  • et un appareil ou un émulateur fonctionnant sous Android 4.4 ou supérieur

1. Créer un projet Firebase

Avant d'utiliser les produits Firebase dans votre application Android, vous devez créer un nouveau projet pour celui-ci dans la console Firebase. Pour ce faire, connectez-vous à la console et appuyez sur le bouton Ajouter un projet bouton dans l'écran d'accueil.

Dans la boîte de dialogue qui apparaît, attribuez un nom explicite au projet, éventuellement un identifiant explicite, puis appuyez sur la touche. Créer un projet bouton.

Une fois le projet créé, vous pouvez définir Firestore comme base de données en accédant à Développer> Base de données et en appuyant sur Essayez Firestore Beta bouton.

Dans l'écran suivant, assurez-vous de choisir le Démarrer en mode test option et appuyez sur le Activer bouton.

À ce stade, vous aurez une base de données Firestore vide, prête à être utilisée dans votre application..

2. Configuration du projet Android

Votre projet Android Studio ne sait toujours rien du projet Firebase que vous avez créé à l'étape précédente. Le moyen le plus simple d’établir une connexion entre les deux est d’utiliser l’assistant Firebase Assistant d’Android Studio..

Aller à Outils> Firebase ouvrir l'assistant.

Firestore étant toujours en version bêta, l'Assistant ne le prend pas encore en charge. Néanmoins, en ajoutant Firebase Analytics à votre application, vous pourrez automatiser la plupart des étapes de configuration requises..

Commencez par cliquer sur le Enregistrer un événement d'analyse lien sous le Analytique section et en appuyant sur la Se connecter à Firebase bouton. Une nouvelle fenêtre de navigateur devrait apparaître vous demandant si vous souhaitez autoriser Android Studio, entre autres choses, à gérer les données Firebase..

appuyez sur la Permettre bouton pour continuer.

De retour dans Android Studio, dans la boîte de dialogue qui s’ouvre, sélectionnez Choisissez un projet Firebase ou Google existant sélectionnez le projet Firebase que vous avez créé précédemment et appuyez sur le bouton Se connecter à Firebase bouton.

Ensuite, appuyez sur le Ajouter des analyses à votre application bouton pour ajouter les dépendances principales de Firebase à votre projet.

Enfin, ajouter Firestore en tant que la mise en oeuvre dépendance, ajoutez la ligne suivante dans le champ app modules build.gradle fichier:

implémentation 'com.google.firebase: firebase-firestore: 11.8.0'

N'oubliez pas d'appuyer sur le Synchroniser maintenant bouton pour terminer la configuration. Si vous rencontrez des erreurs de conflit de version pendant le processus de synchronisation, assurez-vous que les versions de la dépendance Firestore et de la dépendance Firebase Core sont identiques, puis réessayez..

3. Comprendre les documents et les collections

Firestore est une base de données NoSQL qui vous permet de stocker des données sous la forme de documents de type JSON. Cependant, un document qui y est stocké ne peut pas exister indépendamment. Il doit toujours appartenir à une collection. Comme son nom l'indique, une collection n'est qu'un tas de documents. 

Les documents d'une collection sont évidemment des frères et soeurs. Toutefois, si vous souhaitez établir des relations parent-enfant entre eux, vous devez utiliser des sous-collectes. Une sous-collection est simplement une collection qui appartient à un document. Par défaut, un document devient automatiquement le parent de tous les documents appartenant à ses sous-collections..

Il convient également de noter que Firestore gère lui-même la création et la suppression de collections et de sous-collections. Chaque fois que vous essayez d'ajouter un document à une collection inexistante, la collection est créée. De même, une fois que vous supprimez tous les documents d'une collection, il la supprime..

4. Création de documents

Pour pouvoir écrire dans la base de données Firestore à partir de votre application Android, vous devez d’abord en obtenir la référence en appelant le getInstance () méthode du FirebaseFirestore classe.

val myDB = FirebaseFirestore.getInstance ()

Ensuite, vous devez soit créer une nouvelle collection, soit obtenir une référence à une collection existante, en appelant le collection() méthode. Par exemple, sur une base de données vide, le code suivant crée une nouvelle collection nommée système solaire:

val solarSystem = myDB.collection ("solar_system")

Une fois que vous avez une référence à une collection, vous pouvez commencer à y ajouter des documents en appelant sa ajouter() méthode, qui attend une carte comme argument.

// Ajouter un document solarSystem.add (mapOf ("nom" à "Mercure", "nombre" à 1, "gravité" à 3.7)) // Ajouter un autre document solarSystem.add (mapOf ("nom" à "Vénus" , "nombre" à 2, "gravité" à 8,87))

le ajouter() Cette méthode génère et attribue automatiquement un identifiant alphanumérique unique à chaque document créé. Si vous souhaitez que vos documents aient vos propres identifiants personnalisés, vous devez d’abord créer manuellement ces documents en appelant le document() méthode, qui prend une chaîne d'identifiant unique en entrée. Vous pouvez ensuite remplir les documents en appelant le ensemble() méthode qui, comme le ajouter méthode, attend une carte comme seul argument.

Par exemple, le code suivant crée et remplit un nouveau document appelé PLANÈTE TERRE:

solarSystem.document ("PLANET_EARTH") .set (mapOf ("nom" à "Terre", "nombre" à 3, "gravité" à 9,807))

Si vous accédez à la console Firebase et examinez le contenu de la base de données, vous pourrez facilement repérer l’ID personnalisé..

Sachez que si l’ID personnalisé que vous transmettez au document() méthode existe déjà dans la base de données, le ensemble() méthode écrasera le contenu du document associé.

5. Créer des sous-collections

La prise en charge des sous-collections est l’une des fonctionnalités les plus puissantes de Firestore et est ce qui la différencie nettement de la base de données en temps réel Firebase. À l'aide de sous-collections, vous pouvez non seulement ajouter facilement des structures imbriquées à vos données, mais également vous assurer que vos requêtes consomment une quantité minimale de bande passante..

Créer une sous-collection est un peu comme créer une collection. Il vous suffit d'appeler le collection() méthode sur un Référence de document objet et passez une chaîne à celui-ci, qui sera utilisé comme nom de la sous-collection.

Par exemple, le code suivant crée une sous-collection appelée satellites et l'associe au PLANÈTE TERRE document:

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

Une fois que vous avez une référence à une sous-collection, vous êtes libre d'appeler le ajouter() ou ensemble() méthodes pour y ajouter des documents.

satellitesOfEarth.add (mapOf ("nom" de "La Lune", "gravité" de 1.62, "rayon" de 1738))

Après avoir exécuté le code ci-dessus, le PLANÈTE TERRE Le document ressemblera à ceci dans la console Firebase:

6. Exécution de requêtes

Effectuer une opération de lecture sur votre base de données Firestore est très facile si vous connaissez l'ID du document que vous souhaitez lire. Pourquoi? Vous pouvez directement obtenir une référence au document en appelant le collection() et document() méthodes. Par exemple, voici comment vous pouvez obtenir une référence à la PLANÈTE TERRE document qui appartient à la système solaire collection:

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

Pour lire le contenu du document, vous devez appeler le programme asynchrone. obtenir() méthode, qui retourne un Tâche. En ajoutant un OnSuccessListener vous pouvez être averti lorsque l'opération de lecture se termine avec succès.

Le résultat d'une opération de lecture est un DocumentSnapshot objet, qui contient les paires clé-valeur présentes dans le document. En utilisant ses obtenir() méthode, vous pouvez obtenir la valeur de toute clé valide. L'exemple suivant vous montre comment:

planetEarthDoc.get (). addOnSuccessListener println ("Gravity of $ it.get (" name ")) est $ it.get (" gravity ") m / s / s") // SORTIE: // La gravité de la Terre est de 9,807 m / s / s

Si vous ne connaissez pas l'ID du document que vous voulez lire, vous devrez exécuter une requête classique sur toute une collection. L’API Firestore fournit des méthodes de filtrage nommées de manière intuitive, telles que oùEqualTo ()où moins que (), et oùGrandThan (). Comme les méthodes de filtrage peuvent renvoyer plusieurs documents en tant que résultats, vous aurez besoin d’une boucle à l’intérieur de votre document. OnSuccessListener gérer chaque résultat.

Par exemple, pour obtenir le contenu du document de la planète Venus, que nous avons ajouté précédemment, vous pouvez utiliser le code suivant:

myDB.collection ("solar_system") .whereEqualTo ("name", "Venus") .get (). addOnSuccessListener it.forEach println ("Gravité de $ it.get (" nom "") est $ it .get ("gravité") m / s / s ") // SORTIE: // la gravité de Vénus est de 8,87 m / s / s

Enfin, si vous souhaitez lire tous les documents appartenant à une collection, vous pouvez appeler directement le obtenir() méthode sur la collection. Par exemple, voici comment vous pouvez lister toutes les planètes présentes dans le système solaire collection:

myDB.collection ("solar_system") .get (). addOnSuccessListener it.forEach println (it.get ("name")) // SORTIE: // Terre // Vénus // Mercure

Notez que, par défaut, il n'y a pas d'ordre précis dans lequel les résultats sont renvoyés. Si vous souhaitez les commander en fonction d’une clé présente dans tous les résultats, vous pouvez utiliser le commandé par() méthode. Le code suivant ordonne les résultats en fonction de la valeur du nombre clé:

myDB.collection ("solar_system") .orderBy ("numéro") .get (). addOnSuccessListener it.forEach println (it.get ("nom")) // SORTIE: // Mercure // Vénus / / Terre

7. Suppression de données

Pour supprimer un document avec un identifiant connu, il vous suffit d’obtenir une référence, puis d’appeler le effacer() méthode.

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

La suppression de plusieurs documents - les documents obtenus à la suite d'une requête - est légèrement plus compliquée car il n'existe pas de méthode intégrée pour le faire. Il y a deux approches différentes que vous pouvez suivre.

L’approche la plus simple et la plus intuitive, même si elle convient à un très petit nombre de documents, consiste à parcourir les résultats, à obtenir une référence à chaque document, puis à appeler le effacer() méthode. Voici comment vous pouvez utiliser l'approche pour supprimer tous les documents de la système solaire collection:

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

Une approche plus efficace et évolutive consiste à utiliser une opération par lots. Les opérations par lots peuvent non seulement supprimer plusieurs documents de manière atomique, mais également réduire considérablement le nombre de connexions réseau requises.

Pour créer un nouveau lot, vous devez appeler le lot() méthode de votre base de données, qui retourne une instance du WriteBatch classe. Ensuite, vous pouvez parcourir tous les résultats de la requête et les marquer pour suppression en les transmettant au effacer() méthode du WriteBatch objet. Enfin, pour lancer le processus de suppression, vous pouvez appeler le commettre() méthode. Le code suivant vous montre comment:

myDB.collection ("solar_system") .get (). addOnSuccessListener // Créer un lot val myBatch = myDB.batch () // Ajouter des documents au lot it.forEach myBatch.delete (it.reference) // Exécuter un lot myBatch.commit ()

Notez que le fait d’ajouter trop de documents à une seule opération de traitement par lots peut entraîner des erreurs de mémoire insuffisante. Par conséquent, si votre requête est susceptible de renvoyer un grand nombre de documents, vous devez vous assurer de les fractionner en plusieurs lots.

Conclusion

Dans ce didacticiel d’introduction, vous avez appris à effectuer des opérations de lecture et d’écriture sur Google Cloud Firestore. Je vous suggère de commencer à l'utiliser immédiatement dans vos projets Android. Il y a de fortes chances que cette base de données remplace la base de données en temps réel à l'avenir. En fait, Google a déjà annoncé qu’à sa sortie de la version bêta, il serait beaucoup plus fiable et évolutif que la base de données Realtime..

Pour en savoir plus sur Cloud Firestore, vous pouvez vous reporter à sa documentation officielle..

Et pendant que vous êtes ici, consultez certains de nos autres tutoriels sur le développement d'applications Firebase et Android.!