Project Overview & Firebase Setup

Personal Catalogue: React & Firebase

Chapter 1 · Project Overview & Firebase Setup

This is the fourth and last of four courses building the exact same personal cataloguing tool in four genuinely different architectures — Personal Catalogue (PHP & MySQL), Personal Catalogue (Django & PostgreSQL), and Personal Catalogue (React, Express & MongoDB) are all already complete. That third sibling already made the case for a document database over a rigid relational schema; this course takes the same underlying idea — genuinely differently-shaped item records — and answers it with a managed document database instead of a self-run one, so the two can be read side by side as self-managed vs. managed NoSQL.

What the App Actually Does

The shared spec every course in the quartet builds toward, unchanged from the other three:

  • Catalogue four kinds of item — books, CDs, DVDs, and Blu-rays — so it's possible to quickly check "do I already own this CD?" or "what Python books do I have?"
  • Tag books with free-form labels (a FastAPI book might get Python, Web Development, Programming, Web Frameworks) so related books can be found by topic later.
  • Add items manually for the first release — title, author/artist, format-specific details, tags where relevant.
  • Search and browse the collection to answer the "do I have this?" question quickly.

Barcode scanning is explicitly out of scope for this first release — a real, obvious way to add items faster, but deliberately deferred rather than allowed to hold up a release that needs to ship quickly. This is a genuinely personal, single-user tool — nothing in this spec, or in any of its three completed siblings, calls for real user accounts, so this course doesn't build any either.

Why Firestore for This One

The MongoDB sibling's own real argument still holds here: a book's fields (author, ISBN, publisher) and a DVD's fields (director, runtime, disc format) genuinely don't overlap much beyond title and year, so forcing all four item types into one rigid, shared shape either wastes a lot of null columns or splits into several tables that need joining back together for any "show me everything" view. Firestore, Firebase's own document database, gives the identical genuine flexibility — a single items collection can hold a book document and a DVD document side by side, each with only the fields that item type actually needs.

Where the two variants genuinely diverge is what happens after that flexibility is granted. The MongoDB sibling's own Chapter 2 built real, per-type schema validation on top of its flexible collection using Mongoose discriminators — a document that doesn't match its declared item type's schema is rejected before it ever reaches the database. Firestore has no built-in equivalent to that at all: any document, in any shape, can be written to any collection, and Firestore itself will never object. Whatever validation this course ends up wanting has to come from somewhere else — Chapter 2 goes deep on exactly what "somewhere else" means once real code is being written against it.

Flexible Is Not the Same as Validated
"Firestore is schemaless" is true, but it's easy to read that as a pure advantage over the MongoDB sibling's own Mongoose-enforced schemas. It's really a genuine tradeoff: nothing stops a bug from accidentally writing a CD document with a DVD's own field names, and Firestore's own database layer will accept it without complaint. Chapter 2 covers the real options for closing that gap back up.
CourseStackData model
Personal Catalogue: PHP & MySQLClassic LAMPNormalized relational tables, real foreign keys
Personal Catalogue: Django & PostgreSQLPython/Django ORMNormalized relational tables via the ORM
Personal Catalogue: React, Express & MongoDBMERN-styleOne heterogeneous document collection, self-managed, with per-type schema validation via Mongoose discriminators
Personal Catalogue: React & FirebaseReact + managed BaaSOne heterogeneous Firestore collection, managed by Firebase itself, with no built-in schema validation at all

Where Does the Backend Actually Live?

The MongoDB sibling needed a real Express server regardless — MongoDB isn't reachable directly from a browser, so some backend process was always going to exist to hold the connection and expose CRUD routes. Firestore removes that requirement outright: its official client SDK can read and write documents directly from React, with no server of this course's own in between at all. That's a genuine architectural fork worth naming honestly now rather than assuming an answer — direct client-to-Firestore access is faster to build but puts more weight on Firestore's own Security Rules to do the job an Express route's own validation code would otherwise do; a small backend API layer keeps that validation in familiar, testable code at the cost of reintroducing the very server this variant doesn't strictly need. Chapter 3 resolves this for real rather than leaving it open for the rest of the course.

A Question This Course Doesn't Answer Yet
Every real secret this project might need — an API key for a barcode-lookup service, say — belongs behind a server, never in browser-shipped code. But barcode scanning is explicitly deferred past this course's own first release, and nothing else in the shared spec needs an external, secret-holding API call. Whether that means this variant can skip Cloud Functions (Firebase's own serverless functions, the natural home for a real secret) entirely for v1 — genuinely more BaaS-pure than the site's own Food Tracker (React + Firebase) course, which needed one from its own Chapter 3 to proxy two external lookups — is worth watching for as later chapters actually get built, not asserted here.

A Real Deadline, Not Just a Framing Device

This project genuinely needs a working first release quickly, exactly as its three completed siblings each describe. That constraint shapes real decisions here too: a plain add-item form before any real polish, and — a genuine, welcome side effect of picking Firebase specifically — no server of this course's own to write, configure, and keep running, which is itself real time saved against every one of its three siblings. Chapter 8 covers where the remaining corners were deliberately cut given that time pressure.

Setting Up a Firebase Project

Create a project at the Firebase console, then enable Firestore in production mode — not test mode, which allows unrestricted reads and writes and would leave real validation entirely unaddressed from day one. With the project created, bring the Firebase SDK into the React app:

npm install firebase // firebase.js import { initializeApp } from "firebase/app"; import { getFirestore } from "firebase/firestore"; const firebaseConfig = { apiKey: "AIzaSy...", authDomain: "catalogue-xxxx.firebaseapp.com", projectId: "catalogue-xxxx", }; const app = initializeApp(firebaseConfig); export const db = getFirestore(app);
That Config Object Is Not a Secret
Pasting apiKey directly into frontend source code looks alarming coming from a "never expose your API key" mindset. It isn't one: Firebase's client-side config values identify which Firebase project a request is talking to — they don't grant access to anything by themselves. Actual access control is enforced entirely by Security Rules, evaluated on Firebase's own servers for every read and write regardless of what config values the client presents. A genuine secret — a real, third-party API key that must never reach the browser — is exactly what Cloud Functions exist for, which is exactly the open question raised above.
Develop Against Emulators, Not the Live Project
npm install -g firebase-tools, then firebase login and firebase init emulators sets up a local Firestore emulator. Building against that instead of the real cloud project from day one avoids racking up usage and avoids polluting real catalogue data with test writes while this course's own schema is still being worked out in Chapter 2.

Where This Course Is Headed

Data modeling in Firestore, held up directly against the MongoDB sibling's own schema (Chapter 2); resolving the client-SDK-vs-backend-API question raised above for real (Chapter 3); one React form handling several genuinely different item shapes (Chapter 4); tags — attaching, managing, and filtering by tag on books (Chapter 5); search, and Firestore's own real, honest query limitations compared with MongoDB's richer query language (Chapter 6); the list and detail views in React (Chapter 7); fast manual entry given the project's own real deadline (Chapter 8); deployment via Firebase Hosting (Chapter 9); and a capstone integrating this catalogue into the existing Astro-based site, closing with a direct, final comparison of self-managed MongoDB against managed Firestore across the whole project (Chapter 10).

Hands-On Exercises

Exercise 1

Explain the real, load-bearing difference between the MongoDB sibling's own Mongoose discriminators and a plain Firestore collection — specifically, what guarantee discriminators give at write time that Firestore does not, and what has to replace that guarantee in a Firestore-based app.

📄 View solution
Exercise 2

Create a Firebase project with Firestore enabled in production mode, wire up the client SDK in a React app, and confirm a working db reference. Then explain why Firebase's client-side config object is safe to include directly in frontend source code, when a real third-party API key is not.

📄 View solution
Exercise 3

Given that barcode scanning is deferred and nothing else in the shared spec needs a real, secret-holding API call, explain why this variant might not need any Cloud Functions at all for its first release — and name the one real thing that would change that answer once barcode scanning is eventually picked up.

📄 View solution

Chapter 1 Quick Reference

  • The shared app — a personal catalogue for books/CDs/DVDs/Blu-rays, tags on books, manual entry first, barcode scanning deferred, single-user throughout
  • Why this variant — Firestore's own document flexibility matches the MongoDB sibling's, but managed by Firebase rather than self-run
  • The real tradeoff — Firestore has no built-in schema validation the way Mongoose discriminators provide; something else has to fill that gap (Chapter 2)
  • The open architectural question — direct client-to-Firestore writes vs. a small backend API layer, resolved in Chapter 3
  • No Cloud Functions confirmed needed yet — barcode scanning, the one feature that would need a real secret, is deferred past this course's first release
  • Deployment target — Firebase Hosting (Chapter 9)
  • Next chapter: Data Modeling in Firestore, Compared Directly Against the MongoDB Sibling's Own Schema