Check out what’s new from Firebase@ Google I/O 2021, and join our alpha program for early access to the new Remote Config personalization feature. Learn more

Laboratoire de codes Android Cloud Firestore

Buts

Dans ce codelab, vous allez créer une application de recommandation de restaurant sur Android soutenue par Cloud Firestore. Vous apprendrez à:

  • Lire et écrire des données sur Firestore à partir d'une application Android
  • Écoutez les modifications des données Firestore en temps réel
  • Utilisez l'authentification Firebase et les règles de sécurité pour sécuriser les données Firestore
  • Rédiger des requêtes Firestore complexes

Conditions préalables

Avant de commencer ce codelab, assurez-vous d'avoir:

  • Android Studio 4.0 ou supérieur
  • Un émulateur Android
  • Node.js version 10 ou supérieure
  • Java version 8 ou supérieure
  1. Connectez-vous à la console Firebase avec votre compte Google.
  2. Dans la console Firebase , cliquez sur Ajouter un projet .
  3. Comme indiqué dans la capture d'écran ci-dessous, entrez un nom pour votre projet Firebase (par exemple, «Friendly Eats»), puis cliquez sur Continuer .

9d2f625aebcab6af.png

  1. Il se peut que l'on vous demande d'activer Google Analytics, aux fins de ce codelab, votre sélection n'a pas d'importance.
  2. Au bout d'une minute environ, votre projet Firebase sera prêt. Cliquez sur Continuer .

Téléchargez le code

Exécutez la commande suivante pour cloner l'exemple de code pour ce laboratoire de codes. Cela créera un dossier appelé friendlyeats-android sur votre machine:

$ git clone https://github.com/firebase/friendlyeats-android

Si vous n'avez pas git sur votre machine, vous pouvez également télécharger le code directement depuis GitHub.

Importez le projet dans Android Studio. Vous verrez probablement des erreurs de compilation ou peut-être un avertissement concernant un fichier google-services.json manquant. Nous corrigerons cela dans la section suivante.

Ajouter la configuration Firebase

  1. Dans la console Firebase , sélectionnez Présentation du projet dans le menu de navigation de gauche. Cliquez sur le bouton Android pour sélectionner la plate-forme. Lorsque vous com.google.firebase.example.fireeats invité à entrer un nom de package, utilisez com.google.firebase.example.fireeats

73d151ed16016421.png

  1. Cliquez sur Enregistrer l'application et suivez les instructions pour télécharger le fichier google-services.json et déplacez-le dans le dossier app/ de l'exemple de code. Cliquez ensuite sur Suivant .

Dans cet atelier de programmation, vous utiliserez Firebase Emulator Suite pour émuler localement Cloud Firestore et d'autres services Firebase. Cela fournit un environnement de développement local sûr, rapide et gratuit pour créer votre application.

Installez la CLI Firebase

Vous devrez d'abord installer la CLI Firebase . Le moyen le plus simple de le faire est d'utiliser npm :

npm install -g firebase-tools

Si vous n'avez pas npm ou si vous rencontrez une erreur, lisez les instructions d'installation pour obtenir un binaire autonome pour votre plate-forme.

Une fois que vous avez installé l'interface de ligne de commande, l'exécution de firebase --version doit signaler une version de 9.0.0 ou ultérieure:

$ firebase --version
9.0.0

Connexion

Exécutez la firebase login pour connecter la CLI à votre compte Google. Cela ouvrira une nouvelle fenêtre de navigateur pour terminer le processus de connexion. Assurez-vous de choisir le même compte que vous avez utilisé lors de la création de votre projet Firebase précédemment.

À partir du dossier friendlyeats-android , exécutez firebase use --add pour connecter votre projet local à votre projet Firebase. Suivez les invites pour sélectionner le projet que vous avez créé précédemment et si vous êtes invité à choisir un alias, entrez default .

Il est maintenant temps d'exécuter Firebase Emulator Suite et l'application Android FriendlyEats pour la première fois.

Exécutez les émulateurs

Dans votre terminal depuis le répertoire friendlyeats-android , exécutez les firebase emulators:start à démarrer les émulateurs Firebase. Vous devriez voir des journaux comme celui-ci:

$ firebase emulators:start
i  emulators: Starting emulators: auth, firestore
i  firestore: Firestore Emulator logging to firestore-debug.log
i  ui: Emulator UI logging to ui-debug.log

┌─────────────────────────────────────────────────────────────┐
│ ✔  All emulators ready! It is now safe to connect your app. │
│ i  View Emulator UI at http://localhost:4000                │
└─────────────────────────────────────────────────────────────┘

┌────────────────┬────────────────┬─────────────────────────────────┐
│ Emulator       │ Host:Port      │ View in Emulator UI             │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Authentication │ localhost:9099 │ http://localhost:4000/auth      │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Firestore      │ localhost:8080 │ http://localhost:4000/firestore │
└────────────────┴────────────────┴─────────────────────────────────┘
  Emulator Hub running at localhost:4400
  Other reserved ports: 4500

Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.

Vous disposez désormais d'un environnement de développement local complet sur votre machine! Assurez-vous de laisser cette commande en cours d'exécution pour le reste du codelab, votre application Android devra se connecter aux émulateurs.

Connectez l'application aux émulateurs

Ouvrez le fichier FirebaseUtil.java dans Android Studio. Ce fichier contient la logique permettant de connecter les SDK Firebase aux émulateurs locaux exécutés sur votre machine.

En haut du fichier, examinez cette ligne:

    /** Use emulators only in debug builds **/
    private static final boolean sUseEmulators = BuildConfig.DEBUG;

Nous utilisons BuildConfig pour nous assurer que nous ne nous connectons aux émulateurs que lorsque notre application s'exécute en mode debug . Lorsque nous compilons l'application en mode release , cette condition sera fausse.

Jetez maintenant un œil à la méthode getFirestore() :

    public static FirebaseFirestore getFirestore() {
        if (FIRESTORE == null) {
            FIRESTORE = FirebaseFirestore.getInstance();

            // Connect to the Cloud Firestore emulator when appropriate. The host '10.0.2.2' is a
            // special IP address to let the Android emulator connect to 'localhost'.
            if (sUseEmulators) {
                FIRESTORE.useEmulator("10.0.2.2", 8080);
            }
        }

        return FIRESTORE;
    }

Nous pouvons voir qu'il utilise la useEmulator(host, port) pour connecter le SDK Firebase à l'émulateur Firestore local. Tout au long de l'application, nous utiliserons FirebaseUtil.getFirestore() pour accéder à cette instance de FirebaseFirestore afin que nous soyons sûrs que nous nous connectons toujours à l'émulateur Firestore lors de l'exécution en mode debug .

Lancez l'appli

Si vous avez correctement ajouté le fichier google-services.json , le projet doit maintenant être compilé. Dans Android Studio, cliquez sur Créer > Rebuild Project et assurez-vous qu'il n'y a pas d'erreurs restantes.

Dans Android Studio Exécutez l'application sur votre émulateur Android. Au début, un écran "Connexion" vous sera présenté. Vous pouvez utiliser n'importe quel e-mail et mot de passe pour vous connecter à l'application. Ce processus de connexion se connecte à l'émulateur Firebase Authentication, donc aucune véritable information d'identification n'est transmise.

Ouvrez maintenant l'interface utilisateur des émulateurs en accédant à http: // localhost: 4000 dans votre navigateur Web. Cliquez ensuite sur l'onglet Authentification et vous devriez voir le compte que vous venez de créer:

Émulateur d'authentification Firebase

Une fois que vous avez terminé le processus de connexion, vous devriez voir l'écran d'accueil de l'application:

de06424023ffb4b9.png

Bientôt, nous ajouterons des données pour peupler l'écran d'accueil.

Dans cette section, nous écrirons des données dans Firestore afin de pouvoir remplir l'écran d'accueil actuellement vide.

L'objet principal du modèle dans notre application est un restaurant (voir model/Restaurant.java ). Les données Firestore sont divisées en documents, collections et sous-collections. Nous stockerons chaque restaurant sous forme de document dans une collection de premier niveau appelée "restaurants" . Pour en savoir plus sur le modèle de données Firestore, lisez les documents et les collections dans la documentation .

À des fins de démonstration, nous ajouterons des fonctionnalités dans l'application pour créer dix restaurants aléatoires lorsque nous cliquons sur le bouton "Ajouter des éléments aléatoires" dans le menu à débordement. Ouvrez le fichier MainActivity.java et onAddItemsClicked() méthode onAddItemsClicked() :

    private void onAddItemsClicked() {
        // Get a reference to the restaurants collection
        CollectionReference restaurants = mFirestore.collection("restaurants");

        for (int i = 0; i < 10; i++) {
            // Get a random Restaurant POJO
            Restaurant restaurant = RestaurantUtil.getRandom(this);

            // Add a new document to the restaurants collection
            restaurants.add(restaurant);
        }
    }

Il y a quelques points importants à noter à propos du code ci-dessus:

  • Nous avons commencé par faire référence à la collection "restaurants" . Les collections sont créées implicitement lorsque des documents sont ajoutés, il n'était donc pas nécessaire de créer la collection avant d'écrire des données.
  • Les documents peuvent être créés à l'aide de POJO, que nous utilisons pour créer chaque document de restaurant.
  • La méthode add() ajoute un document à une collection avec un ID généré automatiquement, nous n'avons donc pas besoin de spécifier un ID unique pour chaque Restaurant.

Maintenant, exécutez à nouveau l'application et cliquez sur le bouton "Ajouter des éléments aléatoires" dans le menu à développer pour appeler le code que vous venez d'écrire:

95691e9b71ba55e3.png

Ouvrez maintenant l'interface utilisateur des émulateurs en accédant à http: // localhost: 4000 dans votre navigateur Web. Cliquez ensuite sur l'onglet Firestore et vous devriez voir les données que vous venez d'ajouter:

Émulateur d'authentification Firebase

Ces données sont 100% locales à votre machine. En fait, votre vrai projet ne contient même pas encore de base de données Firestore! Cela signifie qu'il est prudent d'expérimenter la modification et la suppression de ces données sans conséquence.

Félicitations, vous venez d'écrire des données sur Firestore! Dans l'étape suivante, nous allons apprendre à afficher ces données dans l'application.

Dans cette étape, nous allons apprendre à récupérer les données de Firestore et à les afficher dans notre application. La première étape pour lire les données de Firestore consiste à créer une Query . Modifiez la méthode onCreate() :

        mFirestore = FirebaseUtil.getFirestore();

        // Get the 50 highest rated restaurants
        mQuery = mFirestore.collection("restaurants")
                .orderBy("avgRating", Query.Direction.DESCENDING)
                .limit(LIMIT);

Nous voulons maintenant écouter la requête, afin d'obtenir tous les documents correspondants et d'être informés des futures mises à jour en temps réel. Étant donné que notre objectif final est de lier ces données à un RecyclerView , nous devons créer une classe RecyclerView.Adapter pour écouter les données.

Ouvrez la classe FirestoreAdapter , qui a déjà été partiellement implémentée. Tout d'abord, faisons en sorte que l'adaptateur implémente EventListener et définissons la fonction onEvent afin qu'il puisse recevoir les mises à jour d'une requête Firestore:

public abstract class FirestoreAdapter<VH extends RecyclerView.ViewHolder>
        extends RecyclerView.Adapter<VH>
        implements EventListener<QuerySnapshot> { // Add this "implements"

    // ...

    // Add this method
    @Override
    public void onEvent(QuerySnapshot documentSnapshots,
                        FirebaseFirestoreException e) {

        // Handle errors
        if (e != null) {
            Log.w(TAG, "onEvent:error", e);
            return;
        }

        // Dispatch the event
        for (DocumentChange change : documentSnapshots.getDocumentChanges()) {
            // Snapshot of the changed document
            DocumentSnapshot snapshot = change.getDocument();

            switch (change.getType()) {
                case ADDED:
                    // TODO: handle document added
                    break;
                case MODIFIED:
                    // TODO: handle document modified
                    break;
                case REMOVED:
                    // TODO: handle document removed
                    break;
            }
        }

        onDataChanged();
    }

  // ...
}

Lors du chargement initial, l'auditeur recevra un événement ADDED pour chaque nouveau document. Au fur et à mesure que le jeu de résultats de la requête change au fil du temps, l'auditeur recevra davantage d'événements contenant les modifications. Maintenant, terminons l'implémentation de l'auditeur. Ajoutez d'abord trois nouvelles méthodes: onDocumentAdded , onDocumentModified et onDocumentRemoved :

    protected void onDocumentAdded(DocumentChange change) {
        mSnapshots.add(change.getNewIndex(), change.getDocument());
        notifyItemInserted(change.getNewIndex());
    }

    protected void onDocumentModified(DocumentChange change) {
        if (change.getOldIndex() == change.getNewIndex()) {
            // Item changed but remained in same position
            mSnapshots.set(change.getOldIndex(), change.getDocument());
            notifyItemChanged(change.getOldIndex());
        } else {
            // Item changed and changed position
            mSnapshots.remove(change.getOldIndex());
            mSnapshots.add(change.getNewIndex(), change.getDocument());
            notifyItemMoved(change.getOldIndex(), change.getNewIndex());
        }
    }

    protected void onDocumentRemoved(DocumentChange change) {
        mSnapshots.remove(change.getOldIndex());
        notifyItemRemoved(change.getOldIndex());
    }

Appelez ensuite ces nouvelles méthodes depuis onEvent :

    @Override
    public void onEvent(QuerySnapshot documentSnapshots,
                        FirebaseFirestoreException e) {

        // ...

        // Dispatch the event
        for (DocumentChange change : documentSnapshots.getDocumentChanges()) {
            // Snapshot of the changed document
            DocumentSnapshot snapshot = change.getDocument();

            switch (change.getType()) {
                case ADDED:
                    onDocumentAdded(change); // Add this line
                    break;
                case MODIFIED:
                    onDocumentModified(change); // Add this line
                    break;
                case REMOVED:
                    onDocumentRemoved(change); // Add this line
                    break;
            }
        }

        onDataChanged();
    }

Enfin, implémentez la méthode startListening() pour attacher l'écouteur:

    public void startListening() {
        if (mQuery != null && mRegistration == null) {
            mRegistration = mQuery.addSnapshotListener(this);
        }
    }

Maintenant, l'application est entièrement configurée pour lire les données de Firestore. Exécutez à nouveau l'application et vous devriez voir les restaurants que vous avez ajoutés à l'étape précédente:

9e45f40faefce5d0.png

Revenez maintenant à l'interface utilisateur de l'émulateur dans votre navigateur et modifiez l'un des noms de restaurant. Vous devriez le voir changer presque instantanément dans l'application!

L'application affiche actuellement les restaurants les mieux notés dans toute la collection, mais dans une vraie application de restaurant, l'utilisateur souhaite trier et filtrer les données. Par exemple, l'application devrait pouvoir afficher "Meilleurs restaurants de fruits de mer à Philadelphie" ou "Pizza la moins chère".

Cliquez sur la barre blanche en haut de l'application pour afficher une boîte de dialogue de filtres. Dans cette section, nous utiliserons les requêtes Firestore pour faire fonctionner cette boîte de dialogue:

67898572a35672a5.png

onFilter() méthode onFilter() de MainActivity.java . Cette méthode accepte un objet Filters qui est un objet d'assistance que nous avons créé pour capturer la sortie de la boîte de dialogue des filtres. Nous allons changer cette méthode pour construire une requête à partir des filtres:

    @Override
    public void onFilter(Filters filters) {
        // Construct query basic query
        Query query = mFirestore.collection("restaurants");

        // Category (equality filter)
        if (filters.hasCategory()) {
            query = query.whereEqualTo("category", filters.getCategory());
        }

        // City (equality filter)
        if (filters.hasCity()) {
            query = query.whereEqualTo("city", filters.getCity());
        }

        // Price (equality filter)
        if (filters.hasPrice()) {
            query = query.whereEqualTo("price", filters.getPrice());
        }

        // Sort by (orderBy with direction)
        if (filters.hasSortBy()) {
            query = query.orderBy(filters.getSortBy(), filters.getSortDirection());
        }

        // Limit items
        query = query.limit(LIMIT);

        // Update the query
        mQuery = query;
        mAdapter.setQuery(query);

        // Set header
        mCurrentSearchView.setText(Html.fromHtml(filters.getSearchDescription(this)));
        mCurrentSortByView.setText(filters.getOrderDescription(this));

        // Save filters
        mViewModel.setFilters(filters);
    }

Dans l'extrait ci - dessus , nous construisons une Query objet en attachant where et orderBy clauses correspondent aux filtres donnés.

Exécutez à nouveau l'application et sélectionnez le filtre suivant pour afficher les restaurants à bas prix les plus populaires:

7a67a8a400c80c50.png

Vous devriez maintenant voir une liste filtrée de restaurants contenant uniquement des options à bas prix:

a670188398c3c59.png

Si vous êtes arrivé jusqu'ici, vous avez maintenant créé une application de visualisation de recommandations de restaurants entièrement fonctionnelle sur Firestore! Vous pouvez désormais trier et filtrer les restaurants en temps réel. Dans les prochaines sections, nous publions des avis et des informations sur la sécurité de l'application.

Dans cette section, nous ajouterons des notes à l'application afin que les utilisateurs puissent consulter leurs restaurants préférés (ou les moins préférés).

Collections et sous-collections

Jusqu'à présent, nous avons stocké toutes les données des restaurants dans une collection de premier niveau appelée «restaurants». Lorsqu'un utilisateur évalue un restaurant, nous voulons ajouter un nouvel objet Rating aux restaurants. Pour cette tâche, nous utiliserons une sous-collection. Vous pouvez considérer une sous-collection comme une collection attachée à un document. Ainsi, chaque document de restaurant aura une sous-collection de notes remplie de documents de notation. Les sous-collections aident à organiser les données sans gonfler nos documents ni nécessiter des requêtes complexes.

Pour accéder à une sous-collection, appelez .collection() sur le document parent:

CollectionReference subRef = mFirestore.collection("restaurants")
        .document("abc123")
        .collection("ratings");

Vous pouvez accéder et interroger une sous-collection tout comme avec une collection de niveau supérieur, il n'y a pas de limitations de taille ou de changements de performances. Pour en savoir plus sur le modèle de données Firestore, cliquez ici .

Ecrire des données dans une transaction

L'ajout d'une Rating à la sous-collection appropriée nécessite uniquement d'appeler .add() , mais nous devons également mettre à jour la note moyenne et le nombre de notes de l'objet Restaurant pour refléter les nouvelles données. Si nous utilisons des opérations distinctes pour effectuer ces deux modifications, il existe un certain nombre de conditions de concurrence qui pourraient entraîner des données périmées ou incorrectes.

Pour nous assurer que les notes sont correctement ajoutées, nous utiliserons une transaction pour ajouter des notes à un restaurant. Cette transaction effectuera quelques actions:

  • Lisez la note actuelle du restaurant et calculez la nouvelle
  • Ajouter la note à la sous-collection
  • Mettre à jour la note moyenne et le nombre de notes du restaurant

Ouvrez RestaurantDetailActivity.java et implémentez la fonction addRating :

    private Task<Void> addRating(final DocumentReference restaurantRef,
                                 final Rating rating) {
        // Create reference for new rating, for use inside the transaction
        final DocumentReference ratingRef = restaurantRef.collection("ratings")
                .document();

        // In a transaction, add the new rating and update the aggregate totals
        return mFirestore.runTransaction(new Transaction.Function<Void>() {
            @Override
            public Void apply(Transaction transaction)
                    throws FirebaseFirestoreException {

                Restaurant restaurant = transaction.get(restaurantRef)
                        .toObject(Restaurant.class);

                // Compute new number of ratings
                int newNumRatings = restaurant.getNumRatings() + 1;

                // Compute new average rating
                double oldRatingTotal = restaurant.getAvgRating() *
                        restaurant.getNumRatings();
                double newAvgRating = (oldRatingTotal + rating.getRating()) /
                        newNumRatings;

                // Set new restaurant info
                restaurant.setNumRatings(newNumRatings);
                restaurant.setAvgRating(newAvgRating);

                // Commit to Firestore
                transaction.set(restaurantRef, restaurant);
                transaction.set(ratingRef, rating);

                return null;
            }
        });
    }

La fonction addRating() renvoie une Task représentant la transaction entière. Dans la fonction onRating() des écouteurs sont ajoutés à la tâche pour répondre au résultat de la transaction.

Exécutez maintenant à nouveau l'application et cliquez sur l' un des restaurants, ce qui devrait faire apparaître l'écran de détail de restaurant. Cliquez sur le bouton + pour commencer à ajouter un avis. Ajoutez un avis en sélectionnant un certain nombre d'étoiles et en saisissant du texte.

78fa16cdf8ef435a.png

Cliquez sur Soumettre pour lancer la transaction. Une fois la transaction terminée, vous verrez votre avis affiché ci-dessous et une mise à jour du nombre d'avis du restaurant:

f9e670f40bd615b0.png

Félicitations! Vous disposez désormais d'une application de révision de restaurant sociale, locale et mobile basée sur Cloud Firestore. J'entends qu'ils sont très populaires ces jours-ci.

Jusqu'à présent, nous n'avons pas considéré la sécurité de cette application. Comment savons-nous que les utilisateurs ne peuvent lire et écrire que les propres données correctes? Les bases de données Firestore sont sécurisées par un fichier de configuration appelé Security Rules .

Ouvrez le fichier firestore.rules , vous devriez voir ce qui suit:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      //
      // WARNING: These rules are insecure! We will replace them with
      // more secure rules later in the codelab
      //
      allow read, write: if request.auth != null;
    }
  }
}

Modifions ces règles pour empêcher les accès ou modifications indésirables aux données, ouvrez le fichier firestore.rules et remplacez le contenu par ce qui suit:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Determine if the value of the field "key" is the same
    // before and after the request.
    function isUnchanged(key) {
      return (key in resource.data)
        && (key in request.resource.data)
        && (resource.data[key] == request.resource.data[key]);
    }

    // Restaurants
    match /restaurants/{restaurantId} {
      // Any signed-in user can read
      allow read: if request.auth != null;

      // Any signed-in user can create
      // WARNING: this rule is for demo purposes only!
      allow create: if request.auth != null;

      // Updates are allowed if no fields are added and name is unchanged
      allow update: if request.auth != null
                    && (request.resource.data.keys() == resource.data.keys())
                    && isUnchanged("name");

      // Deletes are not allowed.
      // Note: this is the default, there is no need to explicitly state this.
      allow delete: if false;

      // Ratings
      match /ratings/{ratingId} {
        // Any signed-in user can read
        allow read: if request.auth != null;

        // Any signed-in user can create if their uid matches the document
        allow create: if request.auth != null
                      && request.resource.data.userId == request.auth.uid;

        // Deletes and updates are not allowed (default)
        allow update, delete: if false;
      }
    }
  }
}

Ces règles limitent l'accès pour garantir que les clients n'effectuent que des modifications sécurisées. Par exemple, les mises à jour d'un document de restaurant ne peuvent modifier que les notes, pas le nom ou toute autre donnée immuable. Les évaluations ne peuvent être créées que si l'ID utilisateur correspond à l'utilisateur connecté, ce qui empêche l'usurpation d'identité.

Pour en savoir plus sur les règles de sécurité, consultez la documentation .

Vous avez maintenant créé une application complète en plus de Firestore. Vous avez découvert les fonctionnalités les plus importantes de Firestore, notamment:

  • Documents et collections
  • Lire et écrire des données
  • Tri et filtrage avec des requêtes
  • Sous-collections
  • Transactions

Apprendre encore plus

Pour continuer à en apprendre davantage sur Firestore, voici quelques bons points pour commencer:

L'application de restaurant de ce codelab était basée sur l'exemple d'application "Friendly Eats". Vous pouvez parcourir le code source de cette application ici .

Facultatif: déployer en production

Jusqu'à présent, cette application n'a utilisé que Firebase Emulator Suite. Si vous souhaitez savoir comment déployer cette application dans un vrai projet Firebase, passez à l'étape suivante.

Jusqu'à présent, cette application était entièrement locale, toutes les données sont contenues dans Firebase Emulator Suite. Dans cette section, vous apprendrez à configurer votre projet Firebase afin que cette application fonctionne en production.

Authentification Firebase

Dans la console Firebase, accédez à la section Authentification et accédez à l' onglet Fournisseurs de connexion .

Activez la méthode de connexion par e-mail:

334ef7f6ff4da4ce.png

Firestore

Créer une base de données

Accédez à la section Firestore de la console et cliquez sur Créer une base de données :

  1. Lorsque vous êtes invité à indiquer que les règles de sécurité choisissent de démarrer en mode verrouillé , nous mettrons à jour ces règles bientôt.
  2. Choisissez l'emplacement de la base de données que vous souhaitez utiliser pour votre application. Notez que la sélection d'un emplacement de base de données est une décision permanente et que pour le modifier, vous devrez créer un nouveau projet. Pour plus d'informations sur le choix d'un emplacement de projet, consultez la documentation .

Déployer des règles

Pour déployer les règles de sécurité que vous avez écrites précédemment, exécutez la commande suivante dans le répertoire codelab:

$ firebase deploy --only firestore:rules

Cela déploiera le contenu de firestore.rules dans votre projet, que vous pourrez confirmer en accédant à l'onglet Règles de la console.

Déployer des index

L'application FriendlyEats a un tri et un filtrage complexes qui nécessitent un certain nombre d'index composés personnalisés. Ceux-ci peuvent être créés à la main dans la console Firebase, mais il est plus simple d'écrire leurs définitions dans le fichier firestore.indexes.json et de les déployer à l'aide de l'interface de ligne de commande Firebase.

Si vous ouvrez le fichier firestore.indexes.json , vous verrez que les index requis ont déjà été fournis:

{
  "indexes": [
    {
      "collectionId": "restaurants",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "city", "mode": "ASCENDING" },
        { "fieldPath": "avgRating", "mode": "DESCENDING" }
      ]
    },
    {
      "collectionId": "restaurants",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "category", "mode": "ASCENDING" },
        { "fieldPath": "avgRating", "mode": "DESCENDING" }
      ]
    },
    {
      "collectionId": "restaurants",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "price", "mode": "ASCENDING" },
        { "fieldPath": "avgRating", "mode": "DESCENDING" }
      ]
    },
    {
      "collectionId": "restaurants",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "city", "mode": "ASCENDING" },
        { "fieldPath": "numRatings", "mode": "DESCENDING" }
      ]
    },
    {
      "collectionId": "restaurants",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "category", "mode": "ASCENDING" },
        { "fieldPath": "numRatings", "mode": "DESCENDING" }
      ]
    },
    {
      "collectionId": "restaurants",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "price", "mode": "ASCENDING" },
        { "fieldPath": "numRatings", "mode": "DESCENDING" }
      ]
    },
    {
      "collectionId": "restaurants",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "city", "mode": "ASCENDING" },
        { "fieldPath": "price", "mode": "ASCENDING" }
      ]
    },
    {
      "collectionId": "restaurants",
      "fields": [
        { "fieldPath": "category", "mode": "ASCENDING" },
        { "fieldPath": "price", "mode": "ASCENDING" }
      ]
    }
  ],
  "fieldOverrides": []
}

Pour déployer ces index, exécutez la commande suivante:

$ firebase deploy --only firestore:indexes

Notez que la création d'index n'est pas instantanée, vous pouvez suivre la progression dans la console Firebase.

Configurer l'appli

Dans la classe FirebaseUtil , nous avons configuré le SDK Firebase pour se connecter aux émulateurs en mode débogage:

public class FirebaseUtil {

    /** Use emulators only in debug builds **/
    private static final boolean sUseEmulators = BuildConfig.DEBUG;

    // ...
}

Si vous souhaitez tester votre application avec votre vrai projet Firebase, vous pouvez soit:

  1. Créez l'application en mode version et exécutez-la sur un appareil.
  2. sUseEmulators temporairement sUseEmulators sur false et réexécutez l'application.

Notez que vous devrez peut-être vous déconnecter de l'application et vous reconnecter pour vous connecter correctement à la production.