Planning d'école multi-utilisateur
Construisez un planning hebdomadaire partagé avec Firebase Authentication et la synchronisation en temps réel
Ce que vous allez construire
Un écran de planning partagé où plusieurs étudiants d'une même école de commerce consultent et gèrent leur emploi du temps de la semaine. Chacun voit ses propres tâches, mais aussi les disponibilités de ses camarades : la coordination des projets de groupe devient simple.
Notions clés
- Authentification : qui utilise l'application ? (Firebase Auth)
- Données multi-utilisateurs : chaque utilisateur a ses propres événements, mais le planning est partagé
- Synchronisation en temps réel : les modifications apparaissent instantanément chez tous les utilisateurs connectés (Firestore)
Prérequis
- Avoir terminé les exercices 1 à 4 du TP 2 (projet Next.js qui tourne en local)
- Un compte Google (pour accéder à la console Firebase)
Cet exercice est facultatif. Il s'adresse aux étudiants qui terminent les travaux pratiques en avance ou qui veulent un défi supplémentaire. Il peut aussi se faire à la maison.
Configurer Firebase
Firebase est la plateforme de Google pour créer des applications sans gérer de serveurs. Elle fournit l'authentification, une base de données en temps réel et l'hébergement, le tout avec une offre gratuite généreuse.
Créer un projet Firebase
- Allez sur console.firebase.google.com et connectez-vous avec votre compte Google
- Cliquez sur « Create a project » (créer un projet) et nommez-le
school-planner - Désactivez Google Analytics (inutile pour cet exercice) et cliquez sur Create
- Une fois le projet créé, cliquez sur l'icône Web (
</>) pour enregistrer une application web - Nommez-la
school-planner-webet cliquez sur Register app (enregistrer l'application) - Copiez l'objet de configuration Firebase : vous en aurez besoin à l'étape suivante
L'objet de configuration ressemble à ceci. Gardez-le sous la main, vous allez bientôt le coller dans votre code :
const firebaseConfig = {
apiKey: "AIza...",
authDomain: "school-planner-xxxxx.firebaseapp.com",
projectId: "school-planner-xxxxx",
storageBucket: "school-planner-xxxxx.appspot.com",
messagingSenderId: "123456789",
appId: "1:123456789:web:abc123"
};
Activer l'authentification
- Dans la barre latérale de la console Firebase, allez dans Build → Authentication
- Cliquez sur Get Started (commencer)
- Activez Email/Password (e-mail et mot de passe) comme fournisseur de connexion
- Vous pouvez aussi activer la connexion Google, plus confortable pour l'utilisateur
Activer la base Firestore
- Allez dans Build → Firestore Database
- Cliquez sur Create database (créer la base)
- Sélectionnez Start in test mode (mode test : toutes les lectures et écritures sont autorisées pendant 30 jours, ce qui suffit pour apprendre)
- Choisissez la région la plus proche (par exemple
europe-west1) et cliquez sur Enable (activer)
Point d'étape : vous avez un projet Firebase avec l'authentification (e-mail et mot de passe) et Firestore activés.
Installer et configurer le SDK Firebase
Installez le SDK JavaScript de Firebase dans votre projet Next.js et créez un fichier de configuration.
Installer le paquet
Dans le terminal de votre projet :
npm install firebase
Créer le fichier de configuration
Demandez à Antigravity de générer la configuration Firebase :
Crée un fichier src/lib/firebase.ts qui :
- initialise Firebase avec ma configuration (ci-dessous)
- exporte l'instance d'authentification (getAuth)
- exporte l'instance de la base Firestore (getFirestore)
- vérifie que Firebase n'est pas initialisé deux fois
Voici ma configuration Firebase :
[collez ici votre objet de configuration]
Le fichier généré doit ressembler à ceci :
import { initializeApp, getApps } from 'firebase/app';
import { getAuth } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
const firebaseConfig = {
apiKey: "your-api-key",
authDomain: "your-project.firebaseapp.com",
projectId: "your-project-id",
storageBucket: "your-project.appspot.com",
messagingSenderId: "123456789",
appId: "your-app-id"
};
const app = getApps().length === 0
? initializeApp(firebaseConfig)
: getApps()[0];
export const auth = getAuth(app);
export const db = getFirestore(app);
Remarque : dans une application de production, ces clés iraient dans des variables d'environnement (.env.local). Pour cet exercice, les placer directement dans le fichier est acceptable : les clés d'API Firebase peuvent être exposées dans le code front-end sans danger (elles sont protégées par les règles de sécurité, pas par le secret).
Point d'étape : src/lib/firebase.ts existe et exporte auth et db. Votre projet compile toujours sans erreur.
Construire l'écran de connexion
Créez une page de connexion et d'inscription pour que chaque étudiant puisse créer un compte et se connecter.
Créer la page de connexion
Demandez à Antigravity :
Crée une page de connexion dans src/app/auth/page.tsx avec :
- une bascule entre les modes "Se connecter" et "S'inscrire"
- un champ e-mail (obligatoire)
- un champ mot de passe (obligatoire, 6 caractères minimum)
- un bouton de validation qui appelle Firebase Auth :
- inscription : createUserWithEmailAndPassword
- connexion : signInWithEmailAndPassword
- l'affichage des messages d'erreur sous le formulaire si la
connexion échoue (par exemple "mot de passe incorrect",
"e-mail déjà utilisé")
- après une connexion réussie, une redirection vers /planning
- en option : un bouton "Se connecter avec Google" qui utilise
signInWithPopup et GoogleAuthProvider
Utilise Tailwind CSS pour le style.
Importe auth depuis "@/lib/firebase".
Tester la page de connexion
- Ouvrez
http://localhost:3000/auth - Créez un compte avec n'importe quelle adresse e-mail et n'importe quel mot de passe
- Vérifiez dans la console Firebase → Authentication → Users : votre nouvel utilisateur doit apparaître
- Déconnectez-vous puis reconnectez-vous pour vérifier que la connexion fonctionne
Astuce : utilisez des adresses de test simples comme alice@school.com et bob@school.com : Firebase ne vérifie pas les adresses e-mail en mode test.
Point d'étape : vous pouvez créer un compte et vous connecter. L'utilisateur apparaît dans la console Firebase Authentication.
Créer le contexte d'authentification
Il vous faut un moyen de savoir quel utilisateur est connecté depuis n'importe quelle page de l'application. C'est le rôle d'un contexte React.
Qu'est-ce qu'un contexte ?
Voyez-le comme une variable globale que n'importe quel composant peut lire. Au lieu de transmettre l'objet utilisateur à la main de page en page, le contexte le rend disponible partout.
Générer le contexte d'authentification
Demandez à Antigravity :
Crée un contexte AuthProvider dans
src/context/AuthContext.tsx qui :
- utilise onAuthStateChanged de Firebase pour suivre
l'utilisateur actuellement connecté
- fournit : l'objet user, un booléen loading et une
fonction signOut
- exporte un hook useAuth() pour y accéder facilement
Ensuite, enveloppe l'application dans AuthProvider dans
src/app/layout.tsx (le provider doit être un composant
client avec "use client").
Si loading vaut true, affiche un indicateur de chargement
ou "Chargement..."
Protéger les routes
Demandez à Antigravity de protéger la page de planning :
Dans src/app/planning/page.tsx (ou dans un layout), vérifie
si l'utilisateur est connecté avec le hook useAuth().
S'il ne l'est pas, redirige vers /auth.
S'il l'est, affiche le contenu de la page.
Ajouter un bouton de déconnexion
Ajoutez à la barre de navigation un bouton de déconnexion qui appelle signOut(auth) et redirige vers /auth.
Point d'étape : ouvrir /planning sans être connecté redirige vers /auth. Une fois connecté, vous accédez à la page de planning. Le bouton de déconnexion fonctionne.
Construire l'écran de planning
C'est la fonctionnalité principale : une grille de calendrier hebdomadaire où tous les étudiants d'une école gèrent ensemble leur emploi du temps.
Le modèle de données
Avant de construire l'interface, comprenez comment les données sont organisées dans Firestore :
schools (collection)
└── my-school (document)
└── events (sub-collection)
├── event1: { userId, userName, title,
│ day, startHour, endHour,
│ color, type }
├── event2: { ... }
└── event3: { ... }
Chaque événement appartient à un utilisateur (userId) mais reste visible par toute l'école.
Générer la page de planning
Demandez à Antigravity de construire la vue complète du planning :
Crée une page de planning dans src/app/planning/page.tsx :
MISE EN PAGE :
- une grille de calendrier hebdomadaire du lundi au vendredi
- des créneaux de 8:00 à 18:00 (une ligne par heure)
- chaque cellule représente une heure d'un jour
- une ligne d'en-tête avec le nom des jours
AJOUT D'ÉVÉNEMENTS :
- un clic sur une cellule vide ouvre une fenêtre modale avec :
- un titre (champ texte)
- un type (liste : class / study / group-project / free)
- l'heure de début et l'heure de fin (listes déroulantes)
- à la validation, enregistre dans Firestore :
chemin de la collection : schools/my-school/events
champs : userId, userName (issus de auth), title, day,
startHour, endHour, color (selon le type), type
AFFICHAGE DES ÉVÉNEMENTS :
- les événements apparaissent en blocs colorés sur la grille
- couleur selon le type : violet=class, cyan=study,
émeraude=group-project, ambre=free
- affiche le titre de l'événement et le nom de l'utilisateur
sur chaque bloc
- les événements de l'utilisateur courant ont une bordure ou
une mise en valeur discrète pour les distinguer
DROITS :
- tous les utilisateurs voient tous les événements
- seul le propriétaire d'un événement peut le modifier ou
le supprimer
- n'affiche les boutons modifier/supprimer que sur les
événements de l'utilisateur
TEMPS RÉEL :
- utilise onSnapshot de Firestore pour écouter les changements
- quand un autre utilisateur ajoute, modifie ou supprime un
événement, l'écran se met à jour automatiquement
Utilise Tailwind CSS. Importe db et auth depuis
"@/lib/firebase". Utilise le hook useAuth().
C'est un gros prompt ! Antigravity peut générer le code en plusieurs étapes. Relisez chaque étape avant de passer à la suivante. Si quelque chose ne fonctionne pas, décrivez le problème à Antigravity et demandez-lui de le corriger.
Point d'étape : la grille de la semaine s'affiche correctement. Vous pouvez cliquer sur une cellule, remplir la fenêtre modale et voir l'événement apparaître dans le calendrier. Vérifiez Firestore dans la console : le document de l'événement doit s'y trouver.
Tester à plusieurs utilisateurs
Tout l'intérêt de cet exercice, c'est que plusieurs utilisateurs collaborent sur le même planning. Vérifions que cela fonctionne.
Ouvrir deux sessions
- Ouvrez votre application dans Chrome et connectez-vous en tant que
alice@school.com - Ouvrez une fenêtre de navigation privée (ou Firefox) et connectez-vous en tant que
bob@school.com - Placez les deux fenêtres côte à côte pour les voir en même temps
Tester la synchronisation en temps réel
- En tant qu'Alice : ajoutez un événement, « Cours de maths » le lundi de 9:00 à 11:00
- Regardez l'écran de Bob : l'événement doit apparaître en 1 à 2 secondes, sans recharger la page
- En tant que Bob : ajoutez un événement, « Groupe de travail » le lundi de 14:00 à 16:00
- Regardez l'écran d'Alice : l'événement de Bob doit apparaître automatiquement
Tester les droits
- En tant que Bob : essayez de modifier ou de supprimer l'événement d'Alice : les boutons modifier/supprimer ne doivent pas être visibles
- En tant qu'Alice : modifiez votre propre événement (par exemple son titre) : la modification doit apparaître sur l'écran de Bob
- En tant qu'Alice : supprimez votre propre événement : il doit disparaître des deux écrans
Travaillez en binôme ! Si vous êtes à côté d'un camarade, connectez-vous tous les deux à la même école et ajoutez des événements en même temps. C'est la façon la plus amusante de tester la synchronisation en temps réel.
Point d'étape : deux utilisateurs peuvent se connecter, ajouter des événements et voir les mises à jour de l'autre en temps réel. Personne ne peut modifier ou supprimer un événement qui appartient à quelqu'un d'autre.
Idées bonus et synthèse
Défis bonus
S'il vous reste du temps, choisissez l'une de ces améliorations :
- Choix de l'école : ajoutez une liste déroulante pour passer d'une école à l'autre (chaque école a sa propre sous-collection d'événements). L'application peut ainsi servir à plusieurs classes.
- Profils utilisateurs : enregistrez les noms affichés et les couleurs d'avatar dans une collection
users, pour que les événements de chacun aient une apparence cohérente. - Glisser et redimensionner : permettez de faire glisser un événement vers un autre créneau ou de le redimensionner pour changer sa durée.
- Détection des conflits : mettez en évidence les créneaux où deux étudiants ou plus ont des événements qui se chevauchent, pratique pour caler une réunion de groupe.
- Export vers un agenda : ajoutez un bouton qui exporte les événements de la semaine dans un fichier
.ics, importable dans Google Agenda ou Outlook.
Ce que vous avez appris
| Notion | À quoi elle sert |
|---|---|
| Firebase Auth | Gère l'inscription, la connexion et les sessions des utilisateurs |
| Firestore | Base de données NoSQL synchronisée en temps réel sur tous les clients |
| React Context | Partage l'état d'authentification entre toutes les pages sans le transmettre de composant en composant (prop drilling) |
| onSnapshot | Écoute les changements en temps réel et met à jour l'interface automatiquement |
| Autorisation | Détermine qui peut modifier ou supprimer une donnée selon son propriétaire |