Firebase et Astro
Firebase est une plate-forme de développement d’applications qui fournit une base de données NoSQL, une authentification, des souscriptions en temps réel, des fonctions et un stockage.
Consultez notre guide dédié au déploiement sur Firebase hosting.
Initialisation de Firebase dans Astro
Titre de la section Initialisation de Firebase dans AstroPrérequis
Titre de la section Prérequis- Un projet Firebase avec une application Web configurée.
- Un projet astro avec server-side rendering (SSR) activé.
- Des identifiants Firebase : vous aurez besoin de deux ensembles d’identifiants pour connecter Astro à Firebase :
- Les identifiants de l’application Web : ces informations d’identification seront utilisées par le côté client de votre application. Vous pouvez les trouver dans la console Firebase sous Paramètres du projet > Général. Faites défiler jusqu’à la section Vos applications et cliquez sur l’icône Application Web.
- Les informations d’identification du projet : ces informations d’identification seront utilisées par le côté serveur de votre application. Vous pouvez les générer dans la console Firebase sous Paramètres du projet > Comptes de service > Firebase Admin SDK > Générer une nouvelle clé privée.
Ajouter les informations d’identification Firebase
Titre de la section Ajouter les informations d’identification FirebasePour ajouter vos informations d’identification Firebase à Astro, créez un fichier « .env » à la racine de votre projet avec les variables suivantes :
FIREBASE_PRIVATE_KEY_ID=YOUR_PRIVATE_KEY_IDFIREBASE_PRIVATE_KEY=YOUR_PRIVATE_KEYFIREBASE_PROJECT_ID=YOUR_PROJECT_IDFIREBASE_CLIENT_EMAIL=YOUR_CLIENT_EMAILFIREBASE_CLIENT_ID=YOUR_CLIENT_IDFIREBASE_AUTH_URI=YOUR_AUTH_URIFIREBASE_TOKEN_URI=YOUR_TOKEN_URIFIREBASE_AUTH_CERT_URL=YOUR_AUTH_CERT_URLFIREBASE_CLIENT_CERT_URL=YOUR_CLIENT_CERT_URL
Désormais, ces variables d’environnement sont disponibles pour être utilisées dans votre projet.
Si vous souhaitez disposer d’IntelliSense pour vos variables d’environnement Firebase, modifiez ou créez le fichier « env.d.ts » dans votre répertoire « src/ » et configurez vos types :
interface ImportMetaEnv { readonly FIREBASE_PRIVATE_KEY_ID: string; readonly FIREBASE_PRIVATE_KEY: string; readonly FIREBASE_PROJECT_ID: string; readonly FIREBASE_CLIENT_EMAIL: string; readonly FIREBASE_CLIENT_ID: string; readonly FIREBASE_AUTH_URI: string; readonly FIREBASE_TOKEN_URI: string; readonly FIREBASE_AUTH_CERT_URL: string readonly FIREBASE_CLIENT_CERT_URL: string;}
interface ImportMeta { readonly env: ImportMetaEnv;}
Apprenez-en plus sur les variables d’environnement et les fichiers .env
dans Astro.
Votre projet devrait à présent inclure les fichiers suivants :
Répertoiresrc/
- env.d.ts
- .env
- astro.config.mjs
- package.json
Installer les dépendances
Titre de la section Installer les dépendancesPour connecter Astro à Firebase, installez les paquets suivants à l’aide de la commande ci-dessous dans votre gestionnaire de paquets préféré :
firebase
- le SDK Firebase pour le côté clientfirebase-admin
- le SDK Firebase Admin pour le côté serveur
npm install firebase firebase-admin
pnpm add firebase firebase-admin
yarn add firebase firebase-admin
Ensuite, créez un dossier nommé firebase
dans le répertoire src/
et ajoutez deux nouveaux fichiers à ce dossier : client.ts
et server.ts
.
Dans client.ts
, ajoutez le code suivant pour initialiser Firebase côté client à l’aide des informations d’identification de votre application Web et du paquet « firebase » :
import { initializeApp } from "firebase/app";
const firebaseConfig = { apiKey: "my-public-api-key", authDomain: "my-auth-domain", projectId: "my-project-id", storageBucket: "my-storage-bucket", messagingSenderId: "my-sender-id", appId: "my-app-id",};
export const app = initializeApp(firebaseConfig);
N’oubliez pas de remplacer l’objet firebaseConfig
par vos propres informations d’identification d’application Web.
Dans server.ts
, ajoutez le code suivant pour initialiser Firebase côté serveur à l’aide des informations d’identification de votre projet et du package firebase-admin
:
import type { ServiceAccount } from "firebase-admin";import { initializeApp, cert, getApps } from "firebase-admin/app";
const activeApps = getApps();const serviceAccount = { type: "service_account", project_id: import.meta.env.FIREBASE_PROJECT_ID, private_key_id: import.meta.env.FIREBASE_PRIVATE_KEY_ID, private_key: import.meta.env.FIREBASE_PRIVATE_KEY, client_email: import.meta.env.FIREBASE_CLIENT_EMAIL, client_id: import.meta.env.FIREBASE_CLIENT_ID, auth_uri: import.meta.env.FIREBASE_AUTH_URI, token_uri: import.meta.env.FIREBASE_TOKEN_URI, auth_provider_x509_cert_url: import.meta.env.FIREBASE_AUTH_CERT_URL, client_x509_cert_url: import.meta.env.FIREBASE_CLIENT_CERT_URL,};
export const app = activeApps.length === 0 ? initializeApp({ credential: cert(serviceAccount as ServiceAccount),}) : activeApps[0];
N’oubliez pas de remplacer l’objet serviceAccount
par vos propres informations d’identification de projet.
À présent, votre projet devrait inclure les fichiers suivants :
Répertoiresrc
- env.d.ts
Répertoirefirebase
- client.ts
- server.ts
- .env
- astro.config.mjs
- package.json
Ajouter l’authentification avec Firebase
Titre de la section Ajouter l’authentification avec FirebasePrérequis
Titre de la section Prérequis- Un projet Astro initialisé avec Firebase.
- Un projet Firebase avec l’authentification par e-mail/mot de passe activée dans la console Firebase sous la méthode Authentification > Connexion.
Créer les points de terminaison du serveur d’authentification
Titre de la section Créer les points de terminaison du serveur d’authentificationL’authentification Firebase dans Astro nécessite les trois points de terminaison du serveur Astro suivants :
GET /api/auth/signin
- pour connecter un utilisateurGET /api/auth/signout
- pour déconnecter un utilisateurPOST /api/auth/register
- pour enregistrer un utilisateur
Créez trois points de terminaison liés à l’authentification dans un nouveau répertoire src/pages/api/auth/
: signin.ts
, signout.ts
et register.ts
.
signin.ts
contient le code nécessaire pour connecter un utilisateur via Firebase :
import type { APIRoute } from "astro";import { app } from "../../../firebase/server";import { getAuth } from "firebase-admin/auth";
export const GET: APIRoute = async ({ request, cookies, redirect }) => { const auth = getAuth(app);
/* Récupération du token depuis les headers de la requête */ const idToken = request.headers.get("Authorization")?.split("Bearer ")[1]; if (!idToken) { return new Response( "No token found", { status: 401 } ); }
/* Vérification du token */ try { await auth.verifyIdToken(idToken); } catch (error) { return new Response( "Invalid token", { status: 401 } ); }
/* Création et configuration du cookie de la session */ const fiveDays = 60 * 60 * 24 * 5 * 1000; const sessionCookie = await auth.createSessionCookie(idToken, { expiresIn: fiveDays, });
cookies.set("session", sessionCookie, { path: "/", });
return redirect("/dashboard");};
Il s’agit d’une implémentation de base du point de terminaison de connexion. Vous pouvez ajouter plus de logique à ce point de terminaison en fonction de vos besoins.
signout.ts
contient le code nécessaire pour déconnecter un utilisateur en supprimant le cookie de session :
import type { APIRoute } from "astro";
export const GET: APIRoute = async ({ redirect, cookies }) => { cookies.delete("session", { path: "/", }); return redirect("/signin");};
Il s’agit d’une implémentation de base du point de terminaison de déconnexion. Vous pouvez ajouter plus de logique à ce point de terminaison en fonction de vos besoins.
register.ts
contient le code nécessaire pour enregistrer un utilisateur via Firebase :
import type { APIRoute } from "astro";import { getAuth } from "firebase-admin/auth";import { app } from "../../../firebase/server";
export const POST: APIRoute = async ({ request, redirect }) => { const auth = getAuth(app);
/* Récupération des données du formulaire */ const formData = await request.formData(); const email = formData.get("email")?.toString(); const password = formData.get("password")?.toString(); const name = formData.get("name")?.toString();
if (!email || !password || !name) { return new Response( "Missing form data", { status: 400 } ); }
/* Création de l'utilisateur */ try { await auth.createUser({ email, password, displayName: name, }); } catch (error: any) { return new Response( "Something went wrong", { status: 400 } ); } return redirect("/signin");};
Il s’agit d’une implémentation de base du point de terminaison d’enregistrement d’utilisateur. Vous pouvez ajouter plus de logique à ce point de terminaison en fonction de vos besoins.
Après avoir créé les points de terminaison serveur concernant l’authentification, votre projet devrait inclure les fichiers suivants :
Répertoiresrc
- env.d.ts
Répertoirefirebase
- client.ts
- server.ts
Répertoirepages
Répertoireapi
Répertoireauth
- signin.ts
- signout.ts
- register.ts
- .env
- astro.config.mjs
- package.json
Création des pages
Titre de la section Création des pagesCréation des pages qui utiliseront les points de terminaison Firebase :
src/pages/register
- contiendra le formulaire d’enregistrement utilisateursrc/pages/signin
- contiendra le formulaire de connexion utilisateursrc/pages/dashboard
- contiendra un tableau de bord uniquement accessible à un utilisateur authentifié
L’exemple src/pages/register.astro
ci-dessous inclut un formulaire qui enverra une requête POST
au point de terminaison /api/auth/register
. Ce point de terminaison créera un nouvel utilisateur en utilisant les données du formulaire, puis redirigera l’utilisateur vers la page /signin
.
---import Layout from "../layouts/Layout.astro";---
<Layout title="Register"> <h1>S'enregistrer</h1> <p>Avez-vous déjà un compte? <a href="/signin">Sign in</a></p> <form action="/api/auth/register" method="post"> <label for="name">Nom</label> <input type="text" name="name" id="name" /> <label for="email" for="email">Email</label> <input type="email" name="email" id="email" /> <label for="password">Mot de passe</label> <input type="password" name="password" id="password" /> <button type="submit">Se Connecter</button> </form></Layout>
src/pages/signin.astro
utilise l’application serveur Firebase pour vérifier le cookie de session de l’utilisateur. Si l’utilisateur est authentifié, la page redirigera l’utilisateur vers la page /dashboard
.
La page d’exemple ci-dessous contient un formulaire qui enverra une requête « POST » au point de terminaison « /api/auth/signin » avec le token d’identification généré par l’application client Firebase.
Le point de terminaison vérifiera le token d’identification et créera un nouveau cookie de session pour l’utilisateur. Ensuite, le point de terminaison redirigera l’utilisateur vers la page « /dashboard ».
---import { app } from "../firebase/server";import { getAuth } from "firebase-admin/auth";import Layout from "../layouts/Layout.astro";
/* On vérifie si l'utilisateur est authentifié */const auth = getAuth(app);if (Astro.cookies.has("session")) { const sessionCookie = Astro.cookies.get("session").value; const decodedCookie = await auth.verifySessionCookie(sessionCookie); if (decodedCookie) { return Astro.redirect("/dashboard"); }}---
<Layout title="S'enregistrer"> <h1>S'enregistrer</h1> <p>Nouveau ici ? <a href="/register">Créer un compte</a></p> <form action="/api/auth/signin" method="post"> <label for="email" for="email">Email</label> <input type="email" name="email" id="email" /> <label for="password">Mot de passe</label> <input type="password" name="password" id="password" /> <button type="submit">Se connecter</button> </form></Layout><script> import { getAuth, inMemoryPersistence, signInWithEmailAndPassword, } from "firebase/auth"; import { app } from "../firebase/client";
const auth = getAuth(app); // Ceci empêchera le navigateur de stocker les données de session auth.setPersistence(inMemoryPersistence);
const form = document.querySelector("form") as HTMLFormElement; form.addEventListener("submit", async (e) => { e.preventDefault(); const formData = new FormData(form); const email = formData.get("email")?.toString(); const password = formData.get("password")?.toString();
if (!email || !password) { return; } const userCredential = await signInWithEmailAndPassword( auth, email, password ); const idToken = await userCredential.user.getIdToken(); const response = await fetch("/api/auth/signin", { method: "GET", headers: { Authorization: `Bearer ${idToken}`, }, });
if (response.redirected) { window.location.assign(response.url); } });</script>
src/pages/dashboard.astro
vérifiera le cookie de session de l’utilisateur à l’aide de l’application serveur Firebase. Si l’utilisateur n’est pas authentifié, la page redirigera l’utilisateur vers la page /signin
.
La page d’exemple ci-dessous affiche le nom de l’utilisateur et un bouton pour se déconnecter. Cliquer sur le bouton enverra une requête GET
au point de terminaison /api/auth/signout
.
Le point de terminaison supprimera le cookie de session de l’utilisateur et redirigera l’utilisateur vers la page « /signin ».
---import { app } from "../firebase/server";import { getAuth } from "firebase-admin/auth";import Layout from "../layouts/Layout.astro";
const auth = getAuth(app);
/* Vérification de la session */if (!Astro.cookies.has("session")) { return Astro.redirect("/signin");}const sessionCookie = Astro.cookies.get("session").value;const decodedCookie = await auth.verifySessionCookie(sessionCookie);const user = await auth.getUser(decodedCookie.uid);
if (!user) { return Astro.redirect("/signin");}---
<Layout title="dashboard"> <h1>Bienvenue {user.displayName}</h1> <p>Nous sommes heureux de te voir ici</p> <form action="/api/auth/signout"> <button type="submit">S'inscrire</button> </form></Layout>
Ajout des fournisseurs OAuth
Titre de la section Ajout des fournisseurs OAuthPour ajouter des fournisseurs OAuth à votre application, vous devez les activer dans la console Firebase.
Dans la console Firebase, accédez à la section Authentification et cliquez sur l’onglet Méthode de connexion. Ensuite, cliquez sur le bouton Ajouter un nouveau fournisseur et activez les fournisseurs que vous souhaitez utiliser.
L’exemple ci-dessous utilise le fournisseur Google.
Modifiez la page signin.astro
pour ajouter :
- un bouton pour se connecter avec Google sous le formulaire existant
- un écouteur d’événement sur le bouton pour gérer le processus de connexion dans le
<script>
existant.
---import { app } from "../firebase/server";import { getAuth } from "firebase-admin/auth";import Layout from "../layouts/Layout.astro";
/* Vérification de l'authentification de l'utilisateur */const auth = getAuth(app);if (Astro.cookies.has("session")) { const sessionCookie = Astro.cookies.get("session").value; const decodedCookie = await auth.verifySessionCookie(sessionCookie); if (decodedCookie) { return Astro.redirect("/dashboard"); }}---
<Layout title="Sign in"> <h1>Sign in</h1> <p>New here? <a href="/register">Create an account</a></p> <form action="/api/auth/signin" method="post"> <label for="email" for="email">Email</label> <input type="email" name="email" id="email" /> <label for="password">Password</label> <input type="password" name="password" id="password" /> <button type="submit">Login</button> </form> <button id="google">Sign in with Google</button></Layout><script> import { getAuth, inMemoryPersistence, signInWithEmailAndPassword, GoogleAuthProvider, signInWithPopup, } from "firebase/auth"; import { app } from "../firebase/client";
const auth = getAuth(app); auth.setPersistence(inMemoryPersistence);
const form = document.querySelector("form") as HTMLFormElement; form.addEventListener("submit", async (e) => { e.preventDefault(); const formData = new FormData(form); const email = formData.get("email")?.toString(); const password = formData.get("password")?.toString();
if (!email || !password) { return; } const userCredential = await signInWithEmailAndPassword( auth, email, password ); const idToken = await userCredential.user.getIdToken(); const response = await fetch("/api/auth/signin", { headers: { Authorization: `Bearer ${idToken}`, }, });
if (response.redirected) { window.location.assign(response.url); } });
const googleSignin = document.querySelector("#google") as HTMLButtonElement; googleSignin.addEventListener("click", async () => { const provider = new GoogleAuthProvider(); const userCredential = await signInWithPopup(auth, provider); const idToken = await userCredential.user.getIdToken(); const res = await fetch("/api/auth/signin", { headers: { Authorization: `Bearer ${idToken}`, }, });
if (res.redirected) { window.location.assign(res.url); } });</script>
Lorsque vous cliquez dessus, le bouton de connexion Google ouvrira une fenêtre contextuelle (popup) pour vous connecter avec Google. Une fois que l’utilisateur s’est connecté, il enverra une requête POST
au endpoint /api/auth/signin
avec le token d’identification généré par le fournisseur OAuth.
Le endpoint vérifiera le token d’identification et créera un nouveau cookie de session pour l’utilisateur. Ensuite, le endpoint redirigera l’utilisateur vers la page /dashboard
.
Connexion à Firestore Database
Titre de la section Connexion à Firestore DatabasePrérequis
Titre de la section Prérequis-
Un projet Astro initialisé avec Firebase comme décrit dans la section Initialisation de Firebase dans Astro.
-
Un projet Firebase avec une base de données Firestore. Vous pouvez suivre la documentation Firebase pour créer un nouveau projet et configurer une base de données Firestore.
Dans cette recette, la collection Firestore s’appellera friends et contiendra des documents avec les champs suivants :
id
: généré automatiquement par Firestorename
: un champ de type stringage
: un champ de type numberisBestFriend
: un champ de type booléen
Création des points de terminaison serveur
Titre de la section Création des points de terminaison serveurCréez deux nouveaux fichiers dans un nouveau répertoire src/pages/api/friends/
: index.ts
et [id].ts
. Ceux-ci créeront deux points de terminaison de serveur pour interagir avec la base de données Firestore des manières suivantes :
POST /api/friends
: pour créer un nouveau document dans la collection “friends”.POST /api/friends/:id
: pour mettre à jour un document dans la collection “friends”.DELETE /api/friends/:id
: pour supprimer un document dans la collection “friends”.
index.ts
contiendra le code pour créer un nouveau document dans la collection “friends” :
import type { APIRoute } from "astro";import { app } from "../../../firebase/server";import { getFirestore } from "firebase-admin/firestore";
export const POST: APIRoute = async ({ request, redirect }) => { const formData = await request.formData(); const name = formData.get("name")?.toString(); const age = formData.get("age")?.toString(); const isBestFriend = formData.get("isBestFriend") === "on";
if (!name || !age) { return new Response("Missing required fields", { status: 400, }); } try { const db = getFirestore(app); const friendsRef = db.collection("friends"); await friendsRef.add({ name, age: parseInt(age), isBestFriend, }); } catch (error) { return new Response("Something went wrong", { status: 500, }); } return redirect("/dashboard");};
Il s’agit d’une implémentation de base du point de terminaison friends
. Vous pouvez ajouter plus de logique à ce point de terminaison en fonction de vos besoins.
[id].ts
contiendra le code pour mettre à jour et supprimer un document dans la collection “friends” :
import type { APIRoute } from "astro";import { app } from "../../../firebase/server";import { getFirestore } from "firebase-admin/firestore";
const db = getFirestore(app);const friendsRef = db.collection("friends");
export const POST: APIRoute = async ({ params, redirect, request }) => { const formData = await request.formData(); const name = formData.get("name")?.toString(); const age = formData.get("age")?.toString(); const isBestFriend = formData.get("isBestFriend") === "on";
if (!name || !age) { return new Response("Missing required fields", { status: 400, }); }
if (!params.id) { return new Response("Cannot find friend", { status: 404, }); }
try { await friendsRef.doc(params.id).update({ name, age: parseInt(age), isBestFriend, }); } catch (error) { return new Response("Something went wrong", { status: 500, }); } return redirect("/dashboard");};
export const DELETE: APIRoute = async ({ params, redirect }) => { if (!params.id) { return new Response("Cannot find friend", { status: 404, }); }
try { await friendsRef.doc(params.id).delete(); } catch (error) { return new Response("Something went wrong", { status: 500, }); } return redirect("/dashboard");};
Il s’agit d’une implémentation de point de terminaison friends/:id
. Vous pouvez ajouter plus de logique à ce point de terminaison en fonction de vos besoins.
Après avoir créé les points de terminaison du serveur pour Firestore, votre répertoire de projet doit maintenant inclure ces nouveaux fichiers :
Répertoiresrc
- env.d.ts
Répertoirefirebase
- client.ts
- server.ts
Répertoirepages
Répertoireapi
Répertoirefriends
- index.ts
- [id].ts
- .env
- astro.config.mjs
- package.json
Création des pages
Titre de la section Création des pagesCréez les pages qui utiliseront les points de terminaison Firestore:
src/pages/add.astro
- contiendra un formulaire permettant d’ajouter un nouvel ami (“friend”).src/pages/edit/[id].astro
- contiendra un formulaire permettant de modifier un ami et un bouton permettant de supprimer un ami.src/pages/friend/[id].astro
- contiendra les informations d’un ami.src/pages/dashboard.astro
- affichera une liste d’amis.
Ajouter une nouvelle entrée
Titre de la section Ajouter une nouvelle entréeL’exemple src/pages/add.astro
ci-dessous inclut un formulaire qui enverra une requête POST
au point de terminaison /api/friends
. Ce point de terminaison créera un nouvel ami en utilisant les données du formulaire, puis redirigera l’utilisateur vers la page /dashboard
.
---import Layout from "../layouts/Layout.astro";---
<Layout title="Ajouter un nouvel ami"> <h1>Ajouter un nouvel ami</h1> <form method="post" action="/api/friends"> <label for="name">Nom</label> <input type="text" id="name" name="name" /> <label for="age">Age</label> <input type="number" id="age" name="age" /> <label for="isBestFriend">C'est mon meilleur ami ?</label> <input type="checkbox" id="isBestFriend" name="isBestFriend" /> <button type="submit">Ajouter</button> </form></Layout>
Modifier ou supprimer une entrée
Titre de la section Modifier ou supprimer une entréesrc/pages/edit/[id].astro
contiendra un formulaire pour modifier les données d’un ami et un bouton pour supprimer un ami. Lors de la soumission, cette page enverra une requête POST
au point de terminaison /api/friends/:id
pour mettre à jour les données d’un ami.
Si l’utilisateur clique sur le bouton Supprimer, cette page enverra une requête DELETE
au point de terminaison /api/friends/:id
pour supprimer un ami.
---import Layout from "../../layouts/Layout.astro";import { app } from "../../firebase/server";import { getFirestore } from "firebase-admin/firestore";
interface Friend { name: string; age: number; isBestFriend: boolean;}
const { id } = Astro.params;
if (!id) { return Astro.redirect("/404");}
const db = getFirestore(app);const friendsRef = db.collection("friends");const friendSnapshot = await friendsRef.doc(id).get();
if (!friendSnapshot.exists) { return Astro.redirect("/404");}
const friend = friendSnapshot.data() as Friend;---
<Layout title="Edit {friend.name}"> <h1>Editer {friend.name}</h1> <p>Ici on peut supprimer ou modifier les données d'un ami.</p> <form method="post" action={`/api/friends/${id}`}> <label for="name">Nom</label> <input type="text" id="name" name="name" value={friend.name} /> <label for="age">Age</label> <input type="number" id="age" name="age" value={friend.age} /> <label for="isBestFriend">C'est mon meilleur ami ?</label> <input type="checkbox" id="isBestFriend" name="isBestFriend" checked={friend.isBestFriend} /> <button type="submit">Editer l'ami</button> </form> <button type="button" id="delete-document">Supprimer</button></Layout><script> const deleteButton = document.getElementById( "delete-document" ) as HTMLButtonElement; const url = document.querySelector("form")?.getAttribute("action") as string; deleteButton.addEventListener("click", async () => { const response = await fetch(url, { method: "DELETE", }); if (response.redirected) { window.location.assign(response.url); } });</script>
Afficher une entrée individuelle
Titre de la section Afficher une entrée individuellesrc/pages/friend/[id].astro
affichera les détails d’un ami.
---import Layout from "../../layouts/Layout.astro";import { app } from "../../firebase/server";import { getFirestore } from "firebase-admin/firestore";
interface Friend { name: string; age: number; isBestFriend: boolean;}
const { id } = Astro.params;
if (!id) { return Astro.redirect("/404");}
const db = getFirestore(app);const friendsRef = db.collection("friends");const friendSnapshot = await friendsRef.doc(id).get();
if (!friendSnapshot.exists) { return Astro.redirect("/404");}
const friend = friendSnapshot.data() as Friend;---
<Layout title={friend.name}> <h1>{friend.name}</h1> <p>Age: {friend.age}</p> <p>C'est mon meilleur ami: {friend.isBestFriend ? "Yes" : "No"}</p></Layout>
Affiche une liste d’entrées avec un bouton d’édition
Titre de la section Affiche une liste d’entrées avec un bouton d’éditionPour terminer, src/pages/dashboard.astro
affichera une liste d’amis. Chaque ami aura un lien vers sa page de détails et un bouton d’édition qui redirigera l’utilisateur vers la page de modification.
---import { app } from "../firebase/server";import { getFirestore } from "firebase-admin/firestore";import Layout from "../layouts/Layout.astro";
interface Friend { id: string; name: string; age: number; isBestFriend: boolean;}
const db = getFirestore(app);const friendsRef = db.collection("friends");const friendsSnapshot = await friendsRef.get();const friends = friendsSnapshot.docs.map((doc) => ({ id: doc.id, ...doc.data(),})) as Friend[];---
<Layout title="My friends"> <h1>Amis</h1> <ul> { friends.map((friend) => ( <li> <a href={`/friend/${friend.id}`}>{friend.name}</a> <span>({friend.age})</span> <strong>{friend.isBestFriend ? "Bestie" : "Friend"}</strong> <a href={`/edit/${friend.id}`}>Editer</a> </li> )) } </ul></Layout>
Après avoir créé toutes les pages, vous devriez avoir la structure de fichiers suivante :
Répertoiresrc
- env.d.ts
Répertoirefirebase
- client.ts
- server.ts
Répertoirepages
- dashboard.astro
- add.astro
Répertoireedit
- [id].astro
Répertoirefriend
- [id].astro
Répertoireapi
Répertoirefriends
- index.ts
- [id].ts
- .env
- astro.config.mjs
- package.json