Step 11: Verification & Commit
Time: ~10 minutes | Type: Testing | Concepts: Quality Assurance, Git Workflow, CRUD Testing
What This Step Is About
Before moving to the next slice, we need to thoroughly test all CRUD operations and commit our code. Data management is critical — bugs here mean lost or corrupted user data.
Full Verification Checklist
Work through this list carefully. Test every scenario!
File Structure
Verify your project has these new files:
src/
├── components/
│ └── Todos/
│ ├── AddTodoForm.tsx (new)
│ ├── EditTodoForm.tsx (new)
│ └── TodosList.tsx (new)
├── lib/
│ └── firebase.ts (updated)
├── pages/
│ ├── AddTodoPage.tsx (new)
│ ├── EditTodoPage.tsx (new)
│ └── TodosPage.tsx (new)
├── types/
│ └── todo.ts (new)
├── App.tsx (updated)
└── components/Layout/Navigation.tsx (updated)Check:
- [ ] All new files exist in correct locations
- [ ] No typos in file names
- [ ] All imports resolve (no red squiggles in IDE)
App Runs Without Errors
npm run devCheck:
- [ ] Dev server starts successfully
- [ ] No errors in terminal
- [ ] Browser console shows no errors on initial load
- [ ] App loads at
http://localhost:5173 - [ ] Authentication still works (can log in)
Firestore Initialization
Check code:
- [ ]
src/lib/firebase.tsexportsdb - [ ]
src/types/todo.tsexportsTodointerface - [ ] Firebase Console → Firestore shows your database
Create (Add) Flow
Test 1: Successful creation
- Navigate to
/todos/new(or click "Add" link) - Title:
Test todo 1 - Description:
Testing create operation - Click submit
Expected:
- [ ] Button shows "Adding..." or "Creating..."
- [ ] No error messages
- [ ] Redirects to
/todos - [ ] New todo appears in list
- [ ] Firebase Console → Firestore → todos shows new document with:
- title: "Test todo 1"
- description: "Testing create operation"
- completed: false
- userId: (your user ID)
- createdAt: (timestamp)
Test 2: Validation
- [ ] Empty title → Shows error "Please enter a title"
- [ ] Form doesn't submit if validation fails
Test 3: Multiple creates
- [ ] Create 3-4 more todos with different titles
- [ ] All appear in Firestore
- [ ] All appear in
/todoslist
Read (List) Flow
Test 1: View todos list
- Go to
/todos
Expected:
- [ ] Brief loading state ("Loading...")
- [ ] All your todos appear
- [ ] Sorted by creation date (newest first)
- [ ] Each todo shows:
- Title
- Description (if present)
- Completed checkbox
- Creation date
- Edit link
- Delete button
Test 2: User isolation
- Log out
- Create a new user account (different email)
- Go to
/todos
Expected:
- [ ] Empty state appears ("No tasks yet!")
- [ ] Don't see the first user's todos
- [ ] Link to add first task works
- Add a todo as this new user
- Log out and log back in as first user
Expected:
- [ ] See only first user's todos
- [ ] Don't see second user's todos
Test 3: Empty state
- Log in as user with no todos (or delete all todos)
- Go to
/todos
Expected:
- [ ] Shows "No tasks yet!" or similar message
- [ ] Shows link to add first task
- [ ] Link works (navigates to
/todos/new)
Update (Edit) Flow
Test 1: Successful update
- On
/todos, click "Edit" next to a todo - Should navigate to
/todos/edit/[id] - Form should pre-fill with todo data
- Change title to "Updated title"
- Change description to "Updated description"
- Toggle completed checkbox
- Click "Update" or "Save"
Expected:
- [ ] Form pre-fills correctly
- [ ] Button shows "Saving..." or "Updating..."
- [ ] No errors
- [ ] Redirects to
/todos - [ ] Updated todo shows new values
- [ ] Firebase Console shows updated document
- [ ] userId and createdAt did NOT change
Test 2: Validation
- [ ] Clear title field → Shows error
- [ ] Form doesn't submit if validation fails
Test 3: Edit multiple todos
- [ ] Edit 2-3 different todos
- [ ] All updates persist correctly
Delete Flow
Test 1: Cancel delete
- On
/todos, click "Delete" on a todo - Confirmation dialog appears
- Click "Cancel"
Expected:
- [ ] Dialog closes
- [ ] Todo remains in list
- [ ] Todo still in Firestore
Test 2: Successful delete
- Click "Delete" on a todo
- Confirm deletion
Expected:
- [ ] Dialog appears asking for confirmation
- [ ] After confirming, todo disappears from list
- [ ] Todo removed from Firestore
- [ ] No errors in console
Test 3: Delete multiple todos
- [ ] Delete 2-3 todos
- [ ] Each deletes successfully
- [ ] List updates after each delete
Test 4: Delete last todo
- Delete all todos until list is empty
Expected:
- [ ] After last delete, empty state appears
- [ ] "No tasks yet!" message shows
- [ ] Link to add first task works
Loading States
Check all loading indicators:
- [ ]
/todosshows loading while fetching - [ ]
/todos/newshows loading on submit button - [ ]
/todos/edit/:idshows loading while fetching todo - [ ]
/todos/edit/:idshows loading on submit button - [ ] Delete button shows loading while deleting
- [ ] Loading prevents double-submissions
Navigation
When logged in:
- [ ] Shows: Home, Todos, Dashboard, Logout
- [ ] Todos link navigates to
/todos
When logged out:
- [ ] Shows: Home, Login, Register
- [ ] Does NOT show: Todos, Dashboard, Logout
- [ ] Trying to access
/todosredirects to/login
Data Persistence
Test 1: Refresh while viewing list
- Go to
/todos(with todos) - Refresh page (F5)
Expected:
- [ ] Todos still appear
- [ ] No data loss
- [ ] No errors
Test 2: Close and reopen browser
- View todos
- Close browser entirely
- Reopen and navigate to
/todos
Expected:
- [ ] Still logged in (if persistence enabled)
- [ ] Todos still present
- [ ] Data intact
Code Quality
Run the linter:
npm run lintCheck:
- [ ] No linting errors
- [ ] No unused imports
- [ ] No TypeScript errors
If errors exist, fix them now before committing.
TypeScript Check
npx tsc --noEmitCheck:
- [ ] No TypeScript compilation errors
- [ ] All types properly defined
- [ ] No
anytypes (or minimal, well-justified)
Common Issues Found During Verification
Todos don't appear after creation
Problem: Not redirecting or not refetching after create.
Fix:
- Verify
navigate('/todos')after successful addDoc - Make sure TodosList fetches on mount with useEffect
User sees other users' todos
Problem: Missing userId filter in query.
Fix:
const q = query(
collection(db, 'todos'),
where('userId', '==', currentUser!.uid), // Must have this!
orderBy('createdAt', 'desc')
);Edit doesn't save changes
Problem: Not awaiting updateDoc or wrong field names.
Fix:
await updateDoc(todoRef, {
title, // Field names must match Firestore
description,
completed
});Delete removes from UI but not Firestore
Problem: Updating state before Firestore delete completes.
Fix:
await deleteDoc(todoRef); // Delete from Firestore first
setTodos(prev => prev.filter(t => t.id !== todoId)); // Then update UISecurity rules blocking operations
Problem: Firestore rules deny read/write.
Fix: Firebase Console → Firestore → Rules (temporary for development):
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /todos/{todoId} {
allow read, write: if request.auth != null;
}
}
}Understanding Your Work
Before committing, make sure you understand what you built:
💡 Final Understanding Check:
Ask yourself (or ask AI if you're unsure):
- What does CRUD stand for and what Firestore function does each?
- Why do we need a userId field on every document?
- What's the difference between getDocs() and getDoc()?
- How does useEffect with empty dependency array work for data fetching?
- Why use updateDoc() instead of setDoc()?
- What happens to deleted Firestore documents (can we undo)?
- Why show loading states during async operations?
- How do Firestore queries improve security and performance?
If you can't answer these, review the earlier steps or ask AI to explain again.
Commit Your Work
IMPORTANT: Only commit if all verification passes!
Check Git Status
git statusYou should see new/modified files like:
src/components/Todos/AddTodoForm.tsx(new)src/components/Todos/EditTodoForm.tsx(new)src/components/Todos/TodosList.tsx(new)src/pages/AddTodoPage.tsx(new)src/pages/EditTodoPage.tsx(new)src/pages/TodosPage.tsx(new)src/types/todo.ts(new)src/lib/firebase.ts(modified)src/App.tsx(modified)src/components/Layout/Navigation.tsx(modified)
Stage Changes
git add src/Commit
git commit -m "Add CRUD operations with Firestore
- Initialize Firestore in firebase config
- Create Todo interface with TypeScript types
- Add create operation: form to add new todos
- Add read operation: list view with queries and loading states
- Add update operation: edit form with pre-filled data
- Add delete operation: delete button with confirmation
- Implement empty state when no todos exist
- Add routes for todos list, add, and edit pages
- Update navigation to include todos link
- Filter todos by userId for user privacy"Why this commit message?
- First line summarizes the feature (< 50 chars)
- Blank line separates subject from body
- Bullet points detail all major changes
- Focuses on "what" was added, not implementation details
Verify Commit
git log -1Should show your commit with the message above.
What You Accomplished
Congratulations! You now have:
✅ Firestore database integrated ✅ TypeScript data model defined ✅ Create operation (add new todos) ✅ Read operation (list todos with queries) ✅ Update operation (edit existing todos) ✅ Delete operation (remove todos with confirmation) ✅ Loading states for all async operations ✅ Empty state for first-time users ✅ User-specific data (privacy via userId filtering) ✅ All CRUD flows tested and verified ✅ All code committed to Git
Skills You Learned
Firestore:
- Initializing Firestore in a React app
- Collections and documents structure
- CRUD operations: addDoc, getDocs, getDoc, updateDoc, deleteDoc
- Queries with where and orderBy
- Timestamps for creation dates
- Document references
React Patterns:
- Fetching data with useEffect
- Managing loading states
- Conditional rendering (loading → empty → list)
- Form handling with controlled components
- URL parameters with useParams
- State updates after async operations
TypeScript:
- Defining data models with interfaces
- Typing Firestore Timestamps
- Optional fields with
? - Typing component props
- Generic types for state
UX:
- Loading indicators
- Empty states with calls-to-action
- Confirmation dialogs for destructive actions
- Form validation and error messages
- Redirects after successful operations
Next Slice
CRUD operations are complete! Users can now create, view, edit, and delete their own todos. Data persists in Firestore and is private to each user.
Next, we'll add security rules to ensure users can only access their own data, even if they try to bypass the UI: