Student starter code (30% baseline)
index.html
- Main HTML pagescript.js
- JavaScript logicstyles.css
- Styling and layoutpackage.json
- Dependenciessetup.sh
- Setup scriptREADME.md
- Instructions (below)๐ก Download the ZIP, extract it, and follow the instructions below to get started!
W3 Server-Side Development & Authentication - Lessons 17-18
Build a full-stack mood tracking application with Firebase Authentication and Firestore Database. This project introduces you to backend services, user authentication, real-time data synchronization, and secure database operations-all essential skills for modern web development.
By completing this project, you will:
onSnapshot
This template is from: Web-3-Project-5-Mood-Tracker
โ
SvelteKit project structure
โ
Firebase SDK dependencies installed
โ
Empty Firebase configuration (firebase.js
)
โ
Basic auth store structure (stores/authStore.js
)
โ
Empty route files for login/signup/dashboard
โ
Development environment setup
User Authentication
Mood Tracking Dashboard
Firebase Integration
State Management
Before running the app, you must set up a Firebase project:
w3-mood-tracker-[your-name]
โ ๏ธ Security Note: Test mode allows read/write for 30 days. Update rules before production!
</>
mood-tracker-web
// Your unique config - COPY THIS
const firebaseConfig = {
apiKey: "AIza...",
authDomain: "your-project.firebaseapp.com",
projectId: "your-project-id",
storageBucket: "your-project.appspot.com",
messagingSenderId: "123456789",
appId: "1:123456789:web:abcdef"
};
Navigate to this project folder:
cd "Paid Courses/W3 Server-Side Development & Authentication/Templates/project-05-mood-tracker"
Open src/firebase.js
in VS Code
Replace the placeholder config with YOUR config:
// src/firebase.js
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
// TODO: Replace with YOUR Firebase config
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_PROJECT.firebaseapp.com",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_PROJECT.appspot.com",
messagingSenderId: "YOUR_SENDER_ID",
appId: "YOUR_APP_ID"
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export const db = getFirestore(app);
Save the file
Install dependencies:
npm install
Start development server:
npm run dev
Open in browser:
Visit http://localhost:5173
project-05-mood-tracker/
โโโ src/
โ โโโ routes/
โ โ โโโ +page.svelte # Dashboard (TODO: implement mood tracking)
โ โ โโโ login/
โ โ โ โโโ +page.svelte # Login page (TODO: implement)
โ โ โโโ signup/
โ โ โโโ +page.svelte # Signup page (TODO: implement)
โ โโโ stores/
โ โ โโโ authStore.js # Auth state management (TODO: complete)
โ โโโ firebase.js # Firebase config (TODO: add your config)
โ โโโ app.html
โโโ package.json
โโโ svelte.config.js
Before implementing, research and answer:
Firebase Authentication: How does Firebase Auth work?
Firestore Database: How do you store data in Firestore?
Real-time Updates: How does onSnapshot
work?
onSnapshot
instead of getDocs
?Security: How do you secure user data?
<!-- src/routes/signup/+page.svelte -->
<script>
import { createUserWithEmailAndPassword } from 'firebase/auth';
import { auth } from '../../firebase';
import { goto } from '$app/navigation';
let email = '';
let password = '';
let error = '';
let loading = false;
async function handleSignup() {
// TODO: Validate inputs
if (password.length < 6) {
error = "Password must be at least 6 characters";
return;
}
loading = true;
error = '';
try {
// TODO: Create user with Firebase
await createUserWithEmailAndPassword(auth, email, password);
// TODO: Redirect to dashboard
await goto('/');
} catch (err) {
// TODO: Handle errors
if (err.code === 'auth/email-already-in-use') {
error = "Email already in use";
} else {
error = "Signup failed. Please try again.";
}
} finally {
loading = false;
}
}
</script>
<!-- TODO: Create signup form UI -->
<!-- src/routes/login/+page.svelte -->
<script>
import { signInWithEmailAndPassword } from 'firebase/auth';
import { auth } from '../../firebase';
let email = '';
let password = '';
let error = '';
async function handleLogin() {
try {
// TODO: Sign in with Firebase
await signInWithEmailAndPassword(auth, email, password);
// Auto-redirect handled by auth state change
} catch (err) {
error = "Invalid email or password";
}
}
</script>
<!-- TODO: Create login form UI -->
<!-- src/routes/+page.svelte -->
<script>
import { onMount } from 'svelte';
import { auth, db } from '../firebase';
import { collection, addDoc, query, where, onSnapshot, orderBy } from 'firebase/firestore';
import { goto } from '$app/navigation';
import authStore from '../stores/authStore';
let mood = '';
let note = '';
let moods = [];
// TODO: Check if user is logged in
onMount(() => {
if (!$authStore.user) {
goto('/login');
return;
}
// TODO: Set up real-time listener for moods
const q = query(
collection(db, 'moods'),
where('userId', '==', $authStore.user.uid),
orderBy('timestamp', 'desc')
);
const unsubscribe = onSnapshot(q, (snapshot) => {
moods = snapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
}));
});
// TODO: Cleanup listener on component destroy
return unsubscribe;
});
async function addMood() {
// TODO: Add mood to Firestore
try {
await addDoc(collection(db, 'moods'), {
userId: $authStore.user.uid,
mood: mood,
note: note,
timestamp: new Date()
});
// Clear form
mood = '';
note = '';
} catch (err) {
console.error('Error adding mood:', err);
}
}
</script>
<!-- TODO: Create mood tracking UI -->
// src/stores/authStore.js
import { writable } from 'svelte/store';
import { auth } from '../firebase';
import { onAuthStateChanged } from 'firebase/auth';
// TODO: Create auth store
const authStore = writable({
user: null,
loading: true,
isLoggedIn: false
});
// TODO: Listen for auth state changes
onAuthStateChanged(auth, (user) => {
authStore.set({
user: user,
loading: false,
isLoggedIn: !!user
});
});
export default authStore;
Your database should follow this structure:
moods (collection)
โโโ [auto-generated-id] (document)
โโโ userId: "user-uid-here"
โโโ mood: "happy"
โโโ note: "Had a great day!"
โโโ timestamp: Firestore Timestamp
Important: Always include userId
to filter user-specific data!
Your project is complete when:
Test these scenarios:
Criteria | Points | Description |
---|---|---|
Authentication | 30 | Signup, login, logout, session management |
Database Operations | 30 | Add moods, real-time updates, user filtering |
Firebase Integration | 20 | Proper config, Auth, Firestore setup |
Security | 10 | User data isolation, protected routes |
Code Quality | 10 | Clean code, error handling, async patterns |
Total | 100 |
Issue: "Firebase: Error (auth/invalid-api-key)"
Solution: Check your Firebase config in firebase.js
- make sure you copied YOUR config correctly
Issue: "Missing or insufficient permissions" Solution: Ensure Firestore is in "test mode" OR update security rules to allow authenticated users
Issue: Auth state not persisting after refresh
Solution: Ensure you're using onAuthStateChanged
in your auth store
Issue: Can see other users' moods
Solution: Add where('userId', '==', user.uid)
to your Firestore query
Issue: Real-time updates not working
Solution: Use onSnapshot
instead of getDocs
, and return the unsubscribe function
// Firestore Rules (for production)
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /moods/{moodId} {
allow read, write: if request.auth != null &&
request.auth.uid == resource.data.userId;
}
}
}
This ensures:
When ready to deploy:
npm run build
npm run preview # Test production build
../../Project/Project 05- Mood Tracker.mdx
Remember: Firebase is powerful but requires proper setup. Take time to configure correctly, and always secure your data with proper rules!
Firebase Setup Issues?
Authentication Problems?
Database Issues?