Intégrer Firebase à une application Next.js

1. Avant de commencer

Dans cet atelier de programmation, vous apprendrez à intégrer Firebase à une application Web Next.js appelée Friendly Eats, qui est un site Web de critiques de restaurants.

Application Web Friendly Eats

L'application Web terminée offre des fonctionnalités utiles qui démontrent comment Firebase peut vous aider à créer des applications Next.js. Ces fonctionnalités incluent les éléments suivants :

  • Fonctionnalité de connexion avec Google et de déconnexion : l'application Web terminée vous permet de vous connecter avec Google et de vous déconnecter. La connexion et la persistance des utilisateurs sont entièrement gérées via l'authentification Firebase .
  • Images : l'application Web terminée permet aux utilisateurs connectés de télécharger des images de restaurant. Les éléments d'image sont stockés dans Cloud Storage pour Firebase . Le SDK JavaScript Firebase fournit une URL publique pour les images téléchargées. Cette URL publique est ensuite stockée dans le document du restaurant concerné dans Cloud Firestore .
  • Avis : l'application Web terminée permet aux utilisateurs connectés de publier des avis sur des restaurants composés d'une note par étoiles et d'un message texte. Les informations d'examen sont stockées dans Cloud Firestore.
  • Filtres : l'application Web terminée permet aux utilisateurs connectés de filtrer la liste des restaurants en fonction de la catégorie, de l'emplacement et du prix. Vous pouvez également personnaliser la méthode de tri utilisée. Les données sont accessibles depuis Cloud Firestore et les requêtes Firestore sont appliquées en fonction des filtres utilisés.

Conditions préalables

  • Connaissance de Next.js et JavaScript

Ce que vous apprendrez

  • Comment utiliser Firebase avec le routeur d'applications Next.js et le rendu côté serveur.
  • Comment conserver des images dans Cloud Storage pour Firebase.
  • Comment lire et écrire des données dans une base de données Cloud Firestore.
  • Comment utiliser la connexion avec Google avec le SDK JavaScript Firebase.

Ce dont vous aurez besoin

  • Git
  • Le kit de développement Java
  • Une version stable récente de Node.js
  • Un navigateur de votre choix, tel que Google Chrome
  • Un environnement de développement avec un éditeur de code et un terminal
  • Un compte Google pour la création et la gestion de votre projet Firebase
  • La possibilité de mettre à niveau votre projet Firebase vers le plan tarifaire Blaze

2. Configurez votre environnement de développement

Cet atelier de programmation fournit la base de code de démarrage de l'application et s'appuie sur la CLI Firebase.

Téléchargez le référentiel

  1. Dans votre terminal, clonez le dépôt GitHub de l'atelier de programmation :
    git clone https://github.com/firebase/friendlyeats-web.git
    
  2. Le référentiel GitHub contient des exemples de projets pour plusieurs plates-formes. Toutefois, cet atelier de programmation utilise uniquement le répertoire nextjs-start . Prenez note des répertoires suivants :
    • nextjs-start : contient le code de démarrage sur lequel vous construisez.
    • nextjs-end : contient le code de solution pour l'application Web terminée.
  3. Dans votre terminal, accédez au répertoire nextjs-start et installez les dépendances nécessaires :
    cd friendlyeats-web/nextjs-start
    npm install
    

Installer ou mettre à jour la CLI Firebase

Exécutez la commande suivante pour vérifier que Firebase CLI est installé et qu'il s'agit de la version 12.5.4 ou ultérieure :

firebase --version
  • Si la CLI Firebase est installée, mais qu'elle n'est pas v12.5.4 ou supérieure, mettez-la à jour :
    npm update -g firebase-tools
    
  • Si la CLI Firebase n'est pas installée, installez-la :
    npm install -g firebase-tools
    

Si vous ne parvenez pas à installer la CLI Firebase en raison d'erreurs d'autorisation, consultez la documentation npm ou utilisez une autre option d'installation .

Connectez-vous à Firebase

  1. Exécutez la commande suivante pour vous connecter à la CLI Firebase :
    firebase login
    
  2. Selon que vous souhaitez que Firebase collecte des données, saisissez Y ou N .
  3. Dans votre navigateur, sélectionnez votre compte Google, puis cliquez sur Autoriser .

3. Configurez votre projet Firebase

Dans cette section, vous allez configurer un projet Firebase et lui associer une application Web Firebase. Vous configurerez également les services Firebase utilisés par l'exemple d'application Web.

Créer un projet Firebase

  1. Dans la console Firebase , cliquez sur Créer un projet .
  2. Dans la zone de texte Saisissez le nom de votre projet , saisissez FriendlyEats Codelab (ou le nom du projet de votre choix), puis cliquez sur Continuer .
  3. Pour cet atelier de programmation, vous n'avez pas besoin de Google Analytics. Désactivez donc l'option Activer Google Analytics pour ce projet .
  4. Cliquez sur Créer un projet .
  5. Attendez que votre projet soit provisionné, puis cliquez sur Continuer .
  6. Dans votre projet Firebase, accédez à Paramètres du projet . Notez votre ID de projet car vous en aurez besoin plus tard. Cet identifiant unique permet d'identifier votre projet (par exemple, dans la CLI Firebase).

Ajoutez une application Web à votre projet Firebase

  1. Accédez à la présentation de votre projet dans votre projet Firebase, puis cliquez sur e41f2efdd9539c31.png La toile .
  2. Dans la zone de texte Pseudonyme d'application , saisissez un surnom d'application mémorable, tel que My Next.js app .
  3. Cochez la case Configurer également Firebase Hosting pour cette application .
  4. Cliquez sur Enregistrer l'application > Suivant > Suivant > Continuer vers la console .

Mettez à niveau votre plan tarifaire Firebase

Pour utiliser des frameworks Web, votre projet Firebase doit être sur le plan tarifaire Blaze , ce qui signifie qu'il est associé à un compte Cloud Billing .

  • Un compte Cloud Billing nécessite un mode de paiement, comme une carte de crédit.
  • Si vous êtes nouveau sur Firebase et Google Cloud, vérifiez si vous êtes éligible à un crédit de 300 $ et à un compte de facturation Cloud d'essai gratuit .

Notez toutefois que la réalisation de cet atelier de programmation ne devrait pas entraîner de frais réels.

Pour mettre à niveau votre projet vers le plan Blaze, procédez comme suit :

  1. Dans la console Firebase, sélectionnez la mise à niveau de votre forfait .
  2. Dans la boîte de dialogue, sélectionnez le forfait Blaze, puis suivez les instructions à l'écran pour associer votre projet à un compte Cloud Billing.
    Si vous deviez créer un compte Cloud Billing, vous devrez peut-être revenir au flux de mise à niveau dans la console Firebase pour terminer la mise à niveau.

Configurer les services Firebase dans la console Firebase

Configurer l'authentification

  1. Dans la console Firebase, accédez à Authentification .
  2. Cliquez sur Commencer .
  3. Dans la colonne Fournisseurs supplémentaires , cliquez sur Google > Activer .
  4. Dans la zone de texte Nom public du projet , entrez un nom mémorable, tel que My Next.js app .
  5. Dans la liste déroulante E-mail d'assistance pour le projet , sélectionnez votre adresse e-mail.
  6. Cliquez sur Enregistrer .

Configurer Cloud Firestore

  1. Dans la console Firebase, accédez à Firestore .
  2. Cliquez sur Créer une base de données > Démarrer en mode test > Suivant .
    Plus loin dans cet atelier de programmation, vous ajouterez des règles de sécurité pour sécuriser vos données. Ne distribuez pas ou n'exposez pas une application publiquement sans ajouter de règles de sécurité pour votre base de données.
  3. Utilisez l'emplacement par défaut ou sélectionnez un emplacement de votre choix.
    Pour une vraie application, vous souhaitez choisir un emplacement proche de vos utilisateurs. Notez que cet emplacement ne peut pas être modifié ultérieurement et qu'il sera également automatiquement l'emplacement de votre bucket Cloud Storage par défaut (étape suivante).
  4. Cliquez sur Terminé .

Configurer le stockage cloud pour Firebase

  1. Dans la console Firebase, accédez à Storage .
  2. Cliquez sur Commencer > Démarrer en mode test > Suivant .
    Plus loin dans cet atelier de programmation, vous ajouterez des règles de sécurité pour sécuriser vos données. Ne distribuez pas ou n'exposez pas une application publiquement sans ajouter de règles de sécurité pour votre compartiment de stockage.
  3. L'emplacement de votre bucket doit déjà être sélectionné (en raison de la configuration de Firestore à l'étape précédente).
  4. Cliquez sur Terminé .

4. Consultez la base de code de démarrage

Dans cette section, vous passerez en revue quelques zones de la base de code de démarrage de l'application auxquelles vous ajouterez des fonctionnalités dans cet atelier de programmation.

Structure des dossiers et des fichiers

Le tableau suivant contient un aperçu de la structure des dossiers et des fichiers de l'application :

Dossiers et fichiers

Description

src/components

Composants React pour les filtres, les en-têtes, les détails du restaurant et les avis

src/lib

Fonctions utilitaires qui ne sont pas nécessairement liées à React ou Next.js

src/lib/firebase

Code spécifique à Firebase et configuration de Firebase

public

Actifs statiques dans l'application Web, comme des icônes

src/app

Routage avec le routeur d'application Next.js

src/app/restaurant

Un gestionnaire de route API

package.json et package-lock.json

Dépendances du projet avec npm

next.config.js

Configuration spécifique à Next.js (les actions du serveur sont activées )

jsconfig.json

Configuration du service de langage JavaScript

Composants serveur et client

L'application est une application Web Next.js qui utilise App Router . Le rendu du serveur est utilisé dans toute l'application. Par exemple, le fichier src/app/page.js est un composant serveur responsable de la page principale. Le fichier src/components/RestaurantListings.jsx est un composant client désigné par la directive "use client" au début du fichier.

Importer des instructions

Vous remarquerez peut-être des instructions d'importation telles que les suivantes :

import RatingPicker from "@/src/components/RatingPicker.jsx";

L'application utilise le symbole @ pour éviter les chemins d'importation relatifs encombrants et est rendue possible par des alias de chemin .

API spécifiques à Firebase

Tout le code de l'API Firebase est encapsulé dans le répertoire src/lib/firebase . Les composants React individuels importent ensuite les fonctions encapsulées à partir du répertoire src/lib/firebase , plutôt que d'importer directement les fonctions Firebase.

Données simulées

Les données fictives du restaurant et des avis sont contenues dans le fichier src/lib/randomData.js . Les données de ce fichier sont assemblées dans le code du fichier src/lib/fakeRestaurants.js .

5. Configurez l'hébergement local avec l'émulateur Firebase Hosting

Dans cette section, vous utiliserez l' émulateur Firebase Hosting pour exécuter l'application Web Next.js localement.

À la fin de cette section, l'émulateur Firebase Hosting exécute l'application Next.js pour vous, vous n'avez donc pas besoin d'exécuter Next.js dans un processus distinct des émulateurs.

Téléchargez et utilisez un compte de service Firebase

L'application Web que vous allez créer dans cet atelier de programmation utilise le rendu côté serveur avec Next.js .

Le SDK Firebase Admin pour Node.js est utilisé pour garantir que les règles de sécurité sont fonctionnelles à partir du code côté serveur. Pour utiliser les API dans Firebase Admin, vous devez télécharger et utiliser un compte de service Firebase depuis la console Firebase.

  1. Dans la console Firebase, accédez à la page Comptes de service dans les paramètres de votre projet .
  2. Cliquez sur Générer une nouvelle clé privée > Générer une clé .
  3. Une fois le fichier téléchargé sur votre système de fichiers, obtenez le chemin complet de ce fichier.
    Par exemple, si vous avez téléchargé le fichier dans votre répertoire Téléchargements , le chemin complet pourrait ressembler à ceci : /Users/me/Downloads/my-project-id-firebase-adminsdk-123.json
  4. Dans votre terminal, définissez la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS sur le chemin de votre clé privée téléchargée. Dans un environnement Unix, la commande pourrait ressembler à ceci :
    export GOOGLE_APPLICATION_CREDENTIALS="/Users/me/Downloads/my-project-id-firebase-adminsdk-123.json"
    
  5. Gardez ce terminal ouvert et utilisez-le pour le reste de cet atelier de programmation, car votre variable d'environnement risque d'être perdue si vous démarrez une nouvelle session de terminal.
    Si vous ouvrez une nouvelle session de terminal, vous devez réexécuter la commande précédente.

Ajoutez votre configuration Firebase au code de votre application Web

  1. Dans la console Firebase, accédez aux paramètres de votre projet .
  2. Dans le volet d'installation et de configuration du SDK , recherchez la variable firebaseConfig et copiez ses propriétés et leurs valeurs.
  3. Ouvrez le fichier .env dans votre éditeur de code et remplissez les valeurs des variables d'environnement avec les valeurs de configuration de la console Firebase.
  4. Dans le fichier, remplacez les propriétés existantes par celles que vous avez copiées.
  5. Enregistrez le fichier.

Initialisez l'application Web avec votre projet Firebase

Pour connecter l'application Web à votre projet Firebase, procédez comme suit :

  1. Dans votre terminal, assurez-vous que les frameworks Web sont activés dans Firebase :
    firebase experiments:enable webframeworks
    
  2. Initialiser Firebase :
    firebase init
    
  3. Sélectionnez les options suivantes :
    • Firestore : configurer les règles de sécurité et les fichiers d'index pour Firestore
    • Hébergement : configurez les fichiers pour l'hébergement Firebase et (éventuellement) configurez les déploiements d'action GitHub
    • Stockage : configurer un fichier de règles de sécurité pour Cloud Storage
    • Émulateurs : configurer des émulateurs locaux pour les produits Firebase
  4. Sélectionnez Utiliser un projet existant , puis entrez l'ID du projet que vous avez noté précédemment.
  5. Sélectionnez les valeurs par défaut pour toutes les questions suivantes jusqu'à ce que vous atteigniez la question Dans quelle région souhaitez-vous héberger le contenu côté serveur, le cas échéant ? . Le terminal affiche un message indiquant qu'il détecte une base de code Next.js existante dans le répertoire actuel.
  6. Pour la question Dans quelle région souhaitez-vous héberger du contenu côté serveur, le cas échéant ? , sélectionnez l'emplacement que vous avez précédemment sélectionné pour Firestore et Cloud Storage.
  7. Sélectionnez les valeurs par défaut pour toutes les questions suivantes jusqu'à ce que vous atteigniez la question Quels émulateurs Firebase souhaitez-vous configurer ? . Pour cette question, sélectionnez Émulateur de fonctions et Émulateur d'hébergement .
  8. Sélectionnez les valeurs par défaut pour toutes les autres questions.

Déployer des règles de sécurité

Le code contient déjà des ensembles de règles de sécurité pour Firestore et pour Cloud Storage pour Firebase. Une fois les règles de sécurité déployées, les données de votre base de données et de votre bucket sont mieux protégées contre toute utilisation abusive.

  1. Pour déployer ces règles de sécurité, exécutez cette commande dans votre terminal :
    firebase deploy --only firestore:rules,storage
    
  2. Si la question vous est posée : "Cloud Storage for Firebase needs an IAM Role to use cross-service rules. Grant the new role?" , sélectionnez Oui .

Démarrez l'émulateur d'hébergement

  1. Dans votre terminal, démarrez l'émulateur d'hébergement :
    firebase emulators:start --only hosting
    
    Votre terminal répond avec le port où vous pouvez trouver l'émulateur d'hébergement, par exemple http://localhost:5000/ .

Terminal indiquant que l'émulateur d'hébergement est prêt

  1. Dans votre navigateur, accédez à l'URL avec l'émulateur Firebase Hosting.
  2. Si vous voyez l'erreur sur la page Web qui commence comme ceci : "Error: Firebase session cookie has incorrect..." , vous devez supprimer tous vos cookies dans votre environnement localhost. Pour ce faire, suivez les instructions dans supprimer les cookies | Documentation des outils de développement .

Une erreur de session de cookie

Supprimer les cookies dans DevTools

Vous pouvez maintenant voir l'application Web initiale ! Même si vous consultez l'application Web sur une URL d'hôte local, elle utilise de vrais services Firebase que vous avez configurés dans votre console.

6. Ajouter l'authentification à l'application Web

Dans cette section, vous ajoutez l'authentification à l'application Web afin de pouvoir vous y connecter.

Implémenter les fonctions de connexion et de déconnexion

  1. Dans le fichier src/lib/firebase/auth.js , remplacez les fonctions onAuthStateChanged , signInWithGoogle et signOut par le code suivant :
export function onAuthStateChanged(cb) {
        return _onAuthStateChanged(auth, cb);
}

export async function signInWithGoogle() {
        const provider = new GoogleAuthProvider();

        try {
                await signInWithPopup(auth, provider);
        } catch (error) {
                console.error("Error signing in with Google", error);
        }
}

export async function signOut() {
        try {
                return auth.signOut();
        } catch (error) {
                console.error("Error signing out with Google", error);
        }
}

Ce code utilise les API Firebase suivantes :

API Firebase

Description

GoogleAuthProvider

Crée une instance de fournisseur d'authentification Google.

signInWithPopup

Démarre un flux d’authentification basé sur une boîte de dialogue.

auth.signOut

Déconnecte l’utilisateur.

Dans le fichier src/components/Header.jsx , le code appelle déjà les fonctions signInWithGoogle et signOut .

  1. Dans l'application Web, actualisez la page et cliquez sur Se connecter avec Google . L'application Web n'est pas mise à jour, il n'est donc pas clair si la connexion a réussi.

Abonnez-vous aux modifications d'authentification

Pour vous abonner aux modifications d'authentification, procédez comme suit :

  1. Accédez au fichier src/components/Header.jsx .
  2. Remplacez la fonction useUserSession par le code suivant :
function useUserSession(initialUser) {
        // The initialUser comes from the server through a server component
        const [user, setUser] = useState(initialUser);
        const router = useRouter();

        useEffect(() => {
                const unsubscribe = onAuthStateChanged(authUser => {
                        setUser(authUser);
                });
                return () => {
                        unsubscribe();
                };
        }, []);

        useEffect(() => {
                onAuthStateChanged(authUser => {
                        if (user === undefined) return;
                        if (user?.email !== authUser?.email) {
                                router.refresh();
                        }
                });
        }, [user]);

        return user;
}

Ce code utilise un hook d'état React pour mettre à jour l'utilisateur lorsque la fonction onAuthStateChanged spécifie qu'il y a un changement dans l'état d'authentification.

Vérifier les modifications

La disposition racine dans le fichier src/app/layout.js restitue l'en-tête et transmet l'utilisateur, si disponible, en tant qu'accessoire.

<Header initialUser={currentUser?.toJSON()} />

Cela signifie que le composant <Header> restitue les données utilisateur, si disponibles, pendant l'exécution du serveur. S'il y a des mises à jour d'authentification pendant le cycle de vie de la page après le chargement initial de la page, le gestionnaire onAuthStateChanged les gère.

Il est maintenant temps de tester l'application Web et de vérifier ce que vous avez créé.

Pour vérifier le nouveau comportement d'authentification, procédez comme suit :

  1. Dans votre navigateur, actualisez l'application Web. Votre nom d’affichage apparaît dans l’en-tête.
  2. Déconnectez-vous et reconnectez-vous. La page est mise à jour en temps réel sans actualisation de la page. Vous pouvez répéter cette étape avec différents utilisateurs.
  3. Facultatif : cliquez avec le bouton droit sur l'application Web, sélectionnez Afficher la source de la page et recherchez le nom d'affichage. Il apparaît dans la source HTML brute renvoyée par le serveur.

7. Afficher les informations sur le restaurant

L'application Web comprend des données fictives pour les restaurants et les avis.

Ajouter un ou plusieurs restaurants

Pour insérer des données de restaurant fictif dans votre base de données Cloud Firestore locale, procédez comme suit :

  1. Dans l'application Web, sélectionnez 2cf67d488d8e6332.png > Ajoutez des exemples de restaurants .
  2. Dans la console Firebase, sur la page Base de données Firestore , sélectionnez restaurants . Vous voyez les documents de niveau supérieur dans la collection de restaurants, chacun représentant un restaurant.
  3. Cliquez sur quelques documents pour explorer les propriétés d'un document de restaurant.

Afficher la liste des restaurants

Votre base de données Cloud Firestore contient désormais des restaurants que l'application Web Next.js peut afficher.

Pour définir le code de récupération de données, procédez comme suit :

  1. Dans le fichier src/app/page.js , recherchez le composant serveur <Home /> et examinez l'appel à la fonction getRestaurants , qui récupère une liste de restaurants au moment de l'exécution du serveur. Vous implémentez la fonction getRestaurants dans les étapes suivantes.
  2. Dans le fichier src/lib/firebase/firestore.js , remplacez les fonctions applyQueryFilters et getRestaurants par le code suivant :
function applyQueryFilters(q, { category, city, price, sort }) {
        if (category) {
                q = query(q, where("category", "==", category));
        }
        if (city) {
                q = query(q, where("city", "==", city));
        }
        if (price) {
                q = query(q, where("price", "==", price.length));
        }
        if (sort === "Rating" || !sort) {
                q = query(q, orderBy("avgRating", "desc"));
        } else if (sort === "Review") {
                q = query(q, orderBy("numRatings", "desc"));
        }
        return q;
}

export async function getRestaurants(filters = {}) {
        let q = query(collection(db, "restaurants"));

        q = applyQueryFilters(q, filters);
        const results = await getDocs(q);
        return results.docs.map(doc => {
                return {
                        id: doc.id,
                        ...doc.data(),
                        // Only plain objects can be passed to Client Components from Server Components
                        timestamp: doc.data().timestamp.toDate(),
                };
        });
}
  1. Actualisez l'application Web. Les images du restaurant apparaissent sous forme de vignettes sur la page.

Vérifiez que les listes de restaurants se chargent au moment de l'exécution du serveur

En utilisant le framework Next.js, cela peut ne pas être évident lorsque les données sont chargées au moment de l'exécution du serveur ou du côté client.

Pour vérifier que les listes de restaurants se chargent au moment de l'exécution du serveur, procédez comme suit :

  1. Dans l'application Web, ouvrez DevTools et désactivez JavaScript .

Désactiver JavaScipt dans DevTools

  1. Actualisez l'application Web. Les listes de restaurants se chargent toujours. Les informations sur le restaurant sont renvoyées dans la réponse du serveur. Lorsque JavaScript est activé, les informations du restaurant sont hydratées via le code JavaScript côté client.
  2. Dans DevTools, réactivez JavaScript .

Écoutez les mises à jour des restaurants avec les écouteurs d'instantanés Cloud Firestore

Dans la section précédente, vous avez vu comment l'ensemble initial de restaurants était chargé à partir du fichier src/app/page.js . Le fichier src/app/page.js est un composant serveur et est rendu sur le serveur, y compris le code de récupération de données Firebase.

Le fichier src/components/RestaurantListings.jsx est un composant client et peut être configuré pour hydrater le balisage rendu par le serveur.

Pour configurer le fichier src/components/RestaurantListings.jsx afin d'hydrater le balisage rendu par le serveur, procédez comme suit :

  1. Dans le fichier src/components/RestaurantListings.jsx , observez le code suivant, qui est déjà écrit pour vous :
useEffect(() => {
        const unsubscribe = getRestaurantsSnapshot(data => {
                setRestaurants(data);
        }, filters);

        return () => {
                unsubscribe();
        };
}, [filters]);

Ce code appelle la fonction getRestaurantsSnapshot() , qui est similaire à la fonction getRestaurants() que vous avez implémentée lors d'une étape précédente. Cependant, cette fonction d'instantané fournit un mécanisme de rappel afin que le rappel soit invoqué à chaque fois qu'une modification est apportée à la collection du restaurant.

  1. Dans le fichier src/lib/firebase/firestore.js , remplacez la fonction getRestaurantsSnapshot() par le code suivant :
export function getRestaurantsSnapshot(cb, filters = {}) {
        if (typeof cb !== "function") {
                console.log("Error: The callback parameter is not a function");
                return;
        }

        let q = query(collection(db, "restaurants"));
        q = applyQueryFilters(q, filters);

        const unsubscribe = onSnapshot(q, querySnapshot => {
                const results = querySnapshot.docs.map(doc => {
                        return {
                                id: doc.id,
                                ...doc.data(),
                                // Only plain objects can be passed to Client Components from Server Components
                                timestamp: doc.data().timestamp.toDate(),
                        };
                });

                cb(results);
        });

        return unsubscribe;
}

Les modifications apportées via la page de base de données Firestore sont désormais reflétées dans l'application Web en temps réel.

  1. Dans l'application Web, sélectionnez 27ca5d1e8ed8adfe.png > Ajoutez des exemples de restaurants . Si votre fonction d'instantané est correctement implémentée, les restaurants apparaissent en temps réel sans actualisation de page.

8. Enregistrez les données utilisateur de l'application Web

  1. Dans le fichier src/lib/firebase/firestore.js , remplacez la fonction updateWithRating() par le code suivant :
const updateWithRating = async (
        transaction,
        docRef,
        newRatingDocument,
        review
) => {
        const restaurant = await transaction.get(docRef);
        const data = restaurant.data();
        const newNumRatings = data?.numRatings ? data.numRatings + 1 : 1;
        const newSumRating = (data?.sumRating || 0) + Number(review.rating);
        const newAverage = newSumRating / newNumRatings;

        transaction.update(docRef, {
                numRatings: newNumRatings,
                sumRating: newSumRating,
                avgRating: newAverage,
        });

        transaction.set(newRatingDocument, {
                ...review,
                timestamp: Timestamp.fromDate(new Date()),
        });
};

Ce code insère un nouveau document Firestore représentant la nouvelle révision. Le code met également à jour le document Firestore existant qui représente le restaurant avec des chiffres mis à jour pour le nombre de notes et la note moyenne calculée.

  1. Remplacez la fonction addReviewToRestaurant() par le code suivant :
export async function addReviewToRestaurant(db, restaurantId, review) {
        if (!restaurantId) {
                throw new Error("No restaurant ID was provided.");
        }

        if (!review) {
                throw new Error("A valid review has not been provided.");
        }

        try {
                const docRef = doc(collection(db, "restaurants"), restaurantId);
                const newRatingDocument = doc(
                        collection(db, `restaurants/${restaurantId}/ratings`)
                );

                await runTransaction(db, transaction =>
                        updateWithRating(transaction, docRef, newRatingDocument, review)
                );
        } catch (error) {
                console.error(
                        "There was an error adding the rating to the restaurant.",
                        error
                );
                throw error;
        }
}

Implémenter une action serveur Next.js

Une action serveur Next.js fournit une API pratique pour accéder aux données du formulaire, telle que data.get("text") pour obtenir la valeur du texte à partir de la charge utile de soumission du formulaire.

Pour utiliser une action serveur Next.js afin de traiter l'envoi du formulaire de révision, procédez comme suit :

  1. Dans le fichier src/components/ReviewDialog.jsx , recherchez l'attribut action dans l'élément <form> .
<form action={handleReviewFormSubmission}>

La valeur de l'attribut action fait référence à une fonction que vous implémentez à l'étape suivante.

  1. Dans le fichier src/app/actions.js , remplacez la fonction handleReviewFormSubmission() par le code suivant :
// This is a next.js server action, which is an alpha feature, so
// use with caution.
// https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions
export async function handleReviewFormSubmission(data) {
        const { app } = await getAuthenticatedAppForUser();
        const db = getFirestore(app);

        await addReviewToRestaurant(db, data.get("restaurantId"), {
                text: data.get("text"),
                rating: data.get("rating"),

                // This came from a hidden form field.
                userId: data.get("userId"),
        });
}

Ajouter des avis pour un restaurant

Vous avez mis en œuvre la prise en charge des soumissions d'avis. Vous pouvez désormais vérifier que vos avis sont correctement insérés dans Cloud Firestore.

Pour ajouter un avis et vérifier qu'il est inséré dans Cloud Firestore, procédez comme suit :

  1. Dans l'application Web, sélectionnez un restaurant sur la page d'accueil.
  2. Sur la page du restaurant, cliquez sur 3e19beef78bb0d0e.png .
  3. Sélectionnez un nombre d'étoiles.
  4. Écrire une critique.
  5. Cliquez sur Soumettre . Votre avis apparaît en haut de la liste des avis.
  6. Dans Cloud Firestore, recherchez dans le volet Ajouter un document le document du restaurant que vous avez examiné et sélectionnez-le.
  7. Dans le volet Démarrer la collecte , sélectionnez évaluations .
  8. Dans le volet Ajouter un document , recherchez le document à réviser pour vérifier qu'il a été inséré comme prévu.

Documents dans l'émulateur Firestore

9. Enregistrez les fichiers téléchargés par l'utilisateur à partir de l'application Web

Dans cette section, vous ajoutez une fonctionnalité afin de pouvoir remplacer l'image associée à un restaurant lorsque vous êtes connecté. Vous téléchargez l'image sur Firebase Storage et mettez à jour l'URL de l'image dans le document Cloud Firestore qui représente le restaurant.

Pour enregistrer les fichiers téléchargés par l'utilisateur à partir de l'application Web, procédez comme suit :

  1. Dans le fichier src/components/Restaurant.jsx , observez le code qui s'exécute lorsque l'utilisateur télécharge un fichier :
async function handleRestaurantImage(target) {
        const image = target.files ? target.files[0] : null;
        if (!image) {
                return;
        }

        const imageURL = await updateRestaurantImage(id, image);
        setRestaurant({ ...restaurant, photo: imageURL });
}

Aucune modification n'est nécessaire, mais vous implémentez le comportement de la fonction updateRestaurantImage() dans les étapes suivantes.

  1. Dans le fichier src/lib/firebase/storage.js , remplacez les fonctions updateRestaurantImage() et uploadImage() par le code suivant :
export async function updateRestaurantImage(restaurantId, image) {
        try {
                if (!restaurantId)
                        throw new Error("No restaurant ID has been provided.");

                if (!image || !image.name)
                        throw new Error("A valid image has not been provided.");

                const publicImageUrl = await uploadImage(restaurantId, image);
                await updateRestaurantImageReference(restaurantId, publicImageUrl);

                return publicImageUrl;
        } catch (error) {
                console.error("Error processing request:", error);
        }
}

async function uploadImage(restaurantId, image) {
        const filePath = `images/${restaurantId}/${image.name}`;
        const newImageRef = ref(storage, filePath);
        await uploadBytesResumable(newImageRef, image);

        return await getDownloadURL(newImageRef);
}

La fonction updateRestaurantImageReference() est déjà implémentée pour vous. Cette fonction met à jour un document de restaurant existant dans Cloud Firestore avec une URL d'image mise à jour.

Vérifier la fonctionnalité de téléchargement d'images

Pour vérifier que l'image est téléchargée comme prévu, procédez comme suit :

  1. Dans l'application Web, vérifiez que vous êtes connecté et sélectionnez un restaurant.
  2. Cliquez sur 7067eb41fea41ff0.png et téléchargez une image depuis votre système de fichiers. Votre image quitte votre environnement local et est téléchargée sur Cloud Storage. L'image apparaît immédiatement après son téléchargement.
  3. Accédez à Cloud Storage pour Firebase.
  4. Accédez au dossier qui représente le restaurant. L'image que vous avez téléchargée existe dans le dossier.

6cf3f9e2303c931c.png

10. Conclusion

Toutes nos félicitations! Vous avez appris à utiliser Firebase pour ajouter des fonctionnalités à une application Next.js. Plus précisément, vous avez utilisé ce qui suit :

Apprendre encore plus