Skip to content

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Learning Check

A live, instructor-driven quiz app for Lansing Tech Studio workshops — like Kahoot, but it loads questions straight from a URL (typically a quiz.json committed into a workshop repo).

An instructor starts a quiz, students join with a 5-character code on their own devices, and the instructor advances question-by-question. After each question the room sees a bar chart of how many students picked each answer with the correct answer highlighted, then moves on. A live leaderboard keeps it fun.

Built to run entirely on Firebase's free Spark plan: React + Vite static hosting, Firestore for live state, and Firebase Auth — no Cloud Functions, no billing required.

How it works

  • Instructor signs in with Google, pastes a quiz URL, and gets a join code.
  • Students open the app, enter the code + a nickname (anonymous auth), and play.
  • Correct answers are never sent to students — they live in a host-only Firestore document and are only revealed when the instructor clicks Reveal. This is enforced by firestore.rules, which act as the backend.

See docs/quiz-schema.md for the quiz file format and docs/sample-quiz.json for a working example.

One-click host links (for slides)

You can link straight into host mode with a quiz pre-loaded — handy for a workshop slide:

https://<your-app>/host?quiz=<url-encoded quiz URL>

You can also set the name-policy default in the link:

https://<your-app>/host?quiz=<url-encoded quiz URL>&randomNamesOnly=1

Accepted truthy values are 1, true, yes, on, or random.

For example, to host the JavaScript Basics quiz:

https://learning-check.web.app/host?quiz=https%3A%2F%2Flansingtechstudio.org%2Fworkshops%2Fjavascript-basics%2Fquiz.json

Opening it signs you in (if needed), fetches the quiz, and drops you straight into the lobby with a join code — no pasting. The URL then becomes …/host?session=CODE, so a refresh resumes the same live session instead of starting a new one.

The easiest way to get one: on the Start a quiz screen, paste your quiz URL and copy the generated 📎 Slide link.

Student name policy controls

Hosts can enforce safer naming in two ways:

  • Moderation filter: offensive names are blocked.
  • Random names only: students must use generated names like PixelNinja.

How random-name policy works:

  • You can set it before launch on Start a quiz.
  • You can include it in static host links via randomNamesOnly=1.
  • While the session is still in Lobby, the host can toggle it on/off.
  • Once the quiz has started, the policy is locked for that session.

When enabled:

  • Student join UI makes nickname entry read-only and directs students to the random button.
  • Host rename controls include a 🎲 Random shortcut.
  • Join/rename is validated in app logic and Firestore rules.

Quick start (local development)

Use Node 24 for local development.

npm install

# Terminal 1 — Firebase Emulator Suite (Auth + Firestore)
npm run emulators

# Terminal 2 — Vite dev server pointed at the emulators
npm run dev:emulators

Open the printed URL. Use one tab as the instructor (/host) and another as a student (/play). Load the bundled sample quiz with the URL http://localhost:5173/sample-quiz.json.

The emulators don't need real Firebase credentials. To run against a real project, copy .env.example to .env.local, fill in your web config, and use npm run dev.

Connecting a real Firebase project (one-time)

  1. Create a project at https://console.firebase.google.com (Spark/free plan is fine).

  2. Build → Firestore Database → create database (production mode).

  3. Build → Authentication → enable the Google and Anonymous providers.

  4. Project settings → Your apps → register a Web app; copy its config into .env.local.

  5. Deploy rules and the app:

    npm run build
    firebase deploy --only firestore:rules,hosting

    (Update the project id in .firebaserc first.)

Scripts

Script What it does
npm run dev Vite dev server (uses .env.local).
npm run dev:emulators Vite dev server pointed at local emulators.
npm run emulators Start the Firebase Emulator Suite.
npm run build Type-check and build to dist/.
npm test Run unit + rules tests (Vitest).

GitHub Actions deploy (main branch)

This repo includes a workflow at .github/workflows/deploy-firebase.yml that:

  • Runs tests and build on every push to main.
  • Deploys to Firebase only if those checks pass.
  • Uses Node 24 in CI.

Set the following repository secret before using it:

  • GCP_SERVICE_ACCOUNT_EMAIL: Service account email used for deploys.
  • GCP_WORKLOAD_IDENTITY_PROVIDER: Full Workload Identity Provider resource name.
    • find this using GCP cloud shell and running gcloud iam workload-identity-pools providers list --project=learning-check --location=global --workload-identity-pool=github-actions-pool --format="value(name)"

The build also needs your Firebase web app config as repository secrets (same values you use in .env.local):

  • VITE_FIREBASE_API_KEY
  • VITE_FIREBASE_AUTH_DOMAIN
  • VITE_FIREBASE_PROJECT_ID
  • VITE_FIREBASE_STORAGE_BUCKET
  • VITE_FIREBASE_MESSAGING_SENDER_ID
  • VITE_FIREBASE_APP_ID

Before the auth with work, also need to enable IAM Service Account Credentials API.

The workflow deploys hosting, firestore.rules, and firestore.indexes.json.

Tech

React 19 · Vite · TypeScript · Tailwind CSS · Firebase (Firestore + Auth + Hosting) · Zod.

About

A quiz used for checking learning of a topic.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages