Personal Catalogue: React & Firebase — Chapter 5, Exercise 1 ===================================================================== TASK Build addTag/removeTag using arrayUnion/arrayRemove and the TagEditor component, then add and remove several tags on a real Book, confirming after each step via the Firebase console that duplicates are never created and removed tags are genuinely gone. SOLUTION // tagOperations.js import { doc, updateDoc, arrayUnion, arrayRemove } from "firebase/firestore"; import { db } from "./firebase"; export async function addTag(bookId, tag) { return updateDoc(doc(db, "items", bookId), { tags: arrayUnion(tag) }); } export async function removeTag(bookId, tag) { return updateDoc(doc(db, "items", bookId), { tags: arrayRemove(tag) }); } Mount TagEditor against a real, already-created Book: console.log(t)} /> Steps and checks (via the Firebase console's data viewer, refreshed after each one): 1. Add "Web Development" -> document's tags: ['Python', 'Web Development'] 2. Add "Python" again -> document's tags: still ['Python', 'Web Development'], confirming arrayUnion's own no-duplicate guarantee — no second 'Python' entry appears. 3. Remove "Python" -> document's tags: ['Web Development'] — the tag is completely gone, not just hidden. 4. Add "Programming" -> document's tags: ['Web Development', 'Programming'] Each check against the console confirms the same state the component's own local console.log reported, meaning the client-side state (built from a real Set to mirror Firestore's own dedupe behavior) never drifted from what was actually saved. WHY THIS WORKS AS AN ANSWER ---------------------------- It builds both functions exactly as the chapter specifies, exercises add/remove/duplicate-add scenarios in sequence rather than only the happy path, and checks the real, authoritative state in the Firebase console after each step rather than trusting the component's own optimistic local update alone.