← Back to Lecture
Bonus Exercise

Multi-User School Planning Screen

Build a shared weekly planner with Firebase Authentication and real-time sync

2-3 hours Intermediate Day 2 Bonus

What You Will Build

A shared planning screen where multiple students within a business school can view and manage their weekly schedule. Each user sees their own tasks and can also see classmates' availability — making group project coordination easy.

Key Concepts

  • Authentication — Who is using the app? (Firebase Auth)
  • Multi-user data — Each user has their own events, but the schedule is shared
  • Real-time sync — Changes appear instantly for all connected users (Firestore)

Prerequisites

  • Completed Practical Work 2, Exercises 1–4 (Next.js project running locally)
  • A Google account (for Firebase console access)

This exercise is optional and designed for students who finish the main practical work early or want an extra challenge. It can also be completed as homework.

Step 1 ~20 min

Set Up Firebase

Firebase is Google's platform for building apps without managing servers. It provides authentication, a real-time database, and hosting — all with a generous free tier.

Create a Firebase Project

  1. Go to console.firebase.google.com and sign in with your Google account
  2. Click "Create a project" and name it school-planner
  3. Disable Google Analytics (not needed for this exercise) and click Create
  4. Once created, click the Web icon (</>) to register a web app
  5. Name it school-planner-web and click Register app
  6. Copy the Firebase config object — you will need it in the next step

The config object looks like this. Keep it handy — you will paste it into your code soon:

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"
};

Enable Authentication

  1. In the Firebase console sidebar, go to Build → Authentication
  2. Click Get Started
  3. Enable Email/Password as a sign-in provider
  4. Optionally enable Google sign-in for a smoother experience

Enable Firestore Database

  1. Go to Build → Firestore Database
  2. Click Create database
  3. Select Start in test mode (allows all reads/writes for 30 days — fine for learning)
  4. Choose the closest region (e.g., europe-west1) and click Enable

Checkpoint: You have a Firebase project with Authentication (Email/Password) and Firestore both enabled.

Step 2 ~15 min

Install & Configure Firebase SDK

Install the Firebase JavaScript SDK in your Next.js project and create a configuration file.

Install the Package

In your project terminal:

npm install firebase

Create the Config File

Ask Antigravity to generate the Firebase configuration:

Create a file src/lib/firebase.ts that:
- Initializes Firebase with my config (below)
- Exports the auth instance (getAuth)
- Exports the Firestore database instance (getFirestore)
- Uses a check to avoid initializing twice

Here is my Firebase config:
[paste your config object here]

The generated file should look something like this:

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);

Note: In a production app, you would store these keys in environment variables (.env.local). For this exercise, putting them directly in the file is acceptable — Firebase API keys are safe to expose in frontend code (they are restricted by security rules, not by secrecy).

Checkpoint: src/lib/firebase.ts exists and exports auth and db. Your project still compiles without errors.

Step 3 ~25 min

Build the Auth Screen

Create a login and signup page so each student can create an account and sign in.

Create the Auth Page

Ask Antigravity:

Create an auth page at src/app/auth/page.tsx with:
- A toggle between "Sign In" and "Sign Up" modes
- Email input field (required)
- Password input field (required, min 6 characters)
- A submit button that calls Firebase Auth:
  - Sign Up: createUserWithEmailAndPassword
  - Sign In: signInWithEmailAndPassword
- Display error messages below the form if login fails
  (e.g., "wrong password", "email already in use")
- On successful sign-in, redirect to /planning
- Optional: a "Sign in with Google" button using
  signInWithPopup and GoogleAuthProvider
Use Tailwind CSS for styling.
Import auth from "@/lib/firebase".

Test the Auth Page

  1. Navigate to http://localhost:3000/auth
  2. Create a new account with any email and password
  3. Check the Firebase console → Authentication → Users — your new user should appear
  4. Sign out and sign back in to verify login works

Tip: Use simple test emails like alice@school.com and bob@school.com — Firebase does not verify email addresses in test mode.

Checkpoint: You can create an account and sign in. The user appears in the Firebase Authentication console.

Step 4 ~20 min

Create the Auth Context

You need a way to know which user is logged in from any page in the app. A React Context provides this.

What is a Context?

Think of it as a global variable that any component can read. Instead of passing the user object through every page manually, the context makes it available everywhere.

Generate the Auth Context

Ask Antigravity:

Create an AuthProvider context at
src/context/AuthContext.tsx that:
- Uses Firebase onAuthStateChanged to track the
  currently signed-in user
- Provides: user object, loading boolean, signOut
  function
- Exports a useAuth() hook for easy access
Then wrap the app with AuthProvider in
src/app/layout.tsx (the provider must be a client
component with "use client").
If loading is true, show a spinner or "Loading..."

Add Route Protection

Ask Antigravity to protect the planning page:

In src/app/planning/page.tsx (or a layout), check if
the user is logged in using the useAuth() hook.
If not logged in, redirect to /auth.
If logged in, show the page content.

Add a Sign Out Button

Add a sign-out button to the navigation bar that calls signOut(auth) and redirects to /auth.

Checkpoint: Visiting /planning when not logged in redirects to /auth. After signing in, you can access the planning page. The sign-out button works.

Step 5 ~40 min

Build the Planning Screen

This is the main feature — a weekly calendar grid where all students in a school can manage their schedule together.

The Data Model

Before building the UI, understand how data is organized in Firestore:

schools (collection)
  └── my-school (document)
        └── events (sub-collection)
              ├── event1: { userId, userName, title,
              │             day, startHour, endHour,
              │             color, type }
              ├── event2: { ... }
              └── event3: { ... }

Each event belongs to a user (userId) but is visible to everyone in the school.

Generate the Planning Page

Ask Antigravity to build the complete planning view:

Create a planning page at src/app/planning/page.tsx:

LAYOUT:
- A weekly calendar grid showing Monday to Friday
- Time slots from 8:00 to 18:00 (one row per hour)
- Each cell represents one hour on one day
- A header row with day names

ADDING EVENTS:
- Clicking an empty cell opens a modal/dialog with:
  - Title (text input)
  - Type (select: class / study / group-project / free)
  - Start hour and end hour (select dropdowns)
- On submit, save to Firestore:
  Collection path: schools/my-school/events
  Fields: userId, userName (from auth), title, day,
  startHour, endHour, color (based on type), type

DISPLAYING EVENTS:
- Events appear as colored blocks on the grid
- Color by type: purple=class, cyan=study,
  emerald=group-project, amber=free
- Show the event title and user name on each block
- Current user's events have a subtle border or
  highlight to distinguish them

PERMISSIONS:
- All users can see all events
- Only the event owner can edit or delete their events
- Show edit/delete buttons only on the user's own
  events

REAL-TIME:
- Use Firestore onSnapshot to listen for changes
- When another user adds/edits/deletes an event,
  it updates on screen automatically

Use Tailwind CSS. Import db and auth from
"@/lib/firebase". Use the useAuth() hook.

This is a big prompt! Antigravity may generate the code in multiple steps. Review each step before moving on. If something doesn't work, describe the problem to Antigravity and ask it to fix it.

Checkpoint: The weekly grid displays correctly. You can click a cell, fill in the modal, and see the event appear on the calendar. Check Firestore in the console — the event document should be there.

Step 6 ~15 min

Test Multi-User

The whole point of this exercise is that multiple users can collaborate on the same planning screen. Let's verify it works.

Set Up Two Sessions

  1. Open your app in Chrome and sign in as alice@school.com
  2. Open an incognito window (or use Firefox) and sign in as bob@school.com
  3. Place both browser windows side by side so you can see both at once

Test Real-Time Sync

  1. As Alice: Add an event — "Math Lecture" on Monday 9:00–11:00
  2. Watch Bob's screen: The event should appear within 1–2 seconds without refreshing
  3. As Bob: Add an event — "Study Group" on Monday 14:00–16:00
  4. Watch Alice's screen: Bob's event should appear automatically

Test Permissions

  1. As Bob: Try to edit or delete Alice's event — the edit/delete buttons should not be visible
  2. As Alice: Edit her own event (e.g., change the title) — the change should appear on Bob's screen
  3. As Alice: Delete her own event — it should disappear from both screens

Pair up! If you are sitting next to a classmate, both sign in to the same school and try adding events at the same time. This is the most fun way to test real-time sync.

Checkpoint: Two users can sign in, add events, and see each other's updates in real-time. Users cannot edit or delete events that belong to someone else.

Wrap Up

Bonus Ideas & Summary

Bonus Challenges

If you have extra time, pick one of these enhancements:

  • School Selector — Add a dropdown to switch between schools (each school has its own events sub-collection). This lets the app support multiple classes.
  • User Profiles — Store display names and avatar colors in a users collection so each person's events have a consistent look.
  • Drag & Resize — Allow users to drag events to different slots or resize them to change duration.
  • Conflict Detection — Highlight time slots where two or more students have overlapping events — useful for scheduling group meetings.
  • Export to Calendar — Add a button that exports the week's events as an .ics file users can import into Google Calendar or Outlook.

What You Learned

Concept What It Does
Firebase Auth Handles user sign-up, sign-in, and session management
Firestore NoSQL database with real-time sync across all clients
React Context Shares auth state across all pages without prop drilling
onSnapshot Listens for real-time changes and updates the UI automatically
Authorization Controls who can edit/delete data based on ownership

Deliverables

Resources

Step Overview