This guide covers the complete backend setup for FitSync, including Firebase Cloud Functions, Firestore configuration, and real-time data syncing.
fitsync/
├── functions/ # Cloud Functions
│ ├── src/
│ │ ├── index.ts # Main functions export
│ │ ├── aggregateDailyStats.ts # Daily aggregation function
│ │ └── chat.ts # Team chat functions
│ ├── package.json
│ └── tsconfig.json
├── src/lib/
│ ├── firebase.ts # Firebase configuration
│ ├── firestore.ts # Firestore service layer
│ └── functionsHelpers.ts # Cloud Functions helpers
├── firestore.rules # Security rules
├── firestore.indexes.json # Database indexes
├── firebase.json # Firebase configuration
└── scripts/ # Deployment scripts
├── setup.sh
├── deploy.sh
└── test-functions.sh
- Node.js (v18 or higher)
- Firebase CLI (
npm install -g firebase-tools) - Firebase Project with ID "fitsync"
- Authentication enabled in Firebase Console
# Run the setup script
npm run setup
# Or manually:
# 1. Install dependencies
npm install
cd functions && npm install && cd ..
# 2. Login to Firebase
firebase login
# 3. Set project
firebase use fitsyncCreate .env.local file in the root directory:
# Firebase Configuration
VITE_FIREBASE_API_KEY=your_api_key_here
VITE_FIREBASE_AUTH_DOMAIN=fitsync.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=fitsync
VITE_FIREBASE_STORAGE_BUCKET=fitsync.firebasestorage.app
VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id_here
VITE_FIREBASE_APP_ID=your_app_id_here
# Firebase Functions Configuration
VITE_FIREBASE_FUNCTIONS_REGION=us-central1
# Development Configuration
VITE_USE_EMULATOR=true
VITE_FIRESTORE_EMULATOR_HOST=localhost
VITE_FIRESTORE_EMULATOR_PORT=8080
VITE_FUNCTIONS_EMULATOR_HOST=localhost
VITE_FUNCTIONS_EMULATOR_PORT=5001
VITE_AUTH_EMULATOR_HOST=localhost
VITE_AUTH_EMULATOR_PORT=9099# Start Firebase emulators
npm run emulators
# In another terminal, start the React app
npm run devThe emulators will be available at:
- Firestore Emulator: http://localhost:8080
- Functions Emulator: http://localhost:5001
- Auth Emulator: http://localhost:9099
- Emulator UI: http://localhost:4000
- Trigger: Daily at 1 AM UTC
- Purpose: Aggregates user activities and creates leaderboards
- Collections Updated:
dailyAggregates/{userId}_{date}leaderboards/{date}
- Purpose: Post messages to team chats
- Authentication: Required
- Validation: Team membership verification
- Purpose: Retrieve team messages with pagination
- Authentication: Required
- Validation: Team membership verification
- Purpose: Health monitoring
- Endpoint:
/api/healthCheck
import { functionsService } from '@/lib/functionsHelpers';
// Post a team message
const result = await functionsService.postTeamMessage({
teamId: 'team123',
message: 'Hello team!',
messageType: 'text'
});
// Get team messages
const messages = await functionsService.getTeamMessages({
teamId: 'team123',
limit: 50
});fitsync/
├── users/ # User profiles
├── activities/ # User activities
├── challenges/ # Wellness challenges
├── teams/ # Team data
│ └── {teamId}/
│ └── messages/ # Team chat messages
├── wellnessMetrics/ # Daily wellness data
├── notifications/ # User notifications
├── dailyAggregates/ # Daily statistics (read-only)
├── leaderboards/ # Leaderboard data (read-only)
├── rewards/ # Available rewards
└── userRewards/ # User reward redemptions
- Users: Can read all profiles, modify only their own
- Activities: Users can only access their own activities
- Teams: Team members can read, admins can modify
- Messages: Only team members can access
- Aggregates/Leaderboards: Read-only for all users
- Rewards: Read-only for all users
All required composite indexes are defined in firestore.indexes.json:
- User queries by wellness score
- Activity queries by user and timestamp
- Challenge queries by status and type
- Message queries by team and timestamp
- And many more...
import { realtimeListeners } from '@/lib/functionsHelpers';
// Team messages
const unsubscribe = realtimeListeners.subscribeToTeamMessages(
'team123',
(messages) => console.log(messages)
);
// User activities
const unsubscribe = realtimeListeners.subscribeToUserActivities(
'user123',
(activities) => console.log(activities)
);
// Rewards
const unsubscribe = realtimeListeners.subscribeToRewards(
(rewards) => console.log(rewards)
);
// Leaderboards
const unsubscribe = realtimeListeners.subscribeToLeaderboards(
'2024-01-15',
(leaderboard) => console.log(leaderboard)
);npm run deploy# Deploy only functions
npm run deploy:functions
# Deploy only Firestore rules
npm run deploy:firestore# Deploy Firestore rules and indexes
firebase deploy --only firestore
# Deploy Cloud Functions
firebase deploy --only functions
# Deploy everything
firebase deploynpm run test:functions- Start emulators:
npm run emulators - Open Emulator UI: http://localhost:4000
- Test functions through the UI
- Use the React app to test real-time features
- Create test users in Auth Emulator
- Test protected functions
- Verify security rules
# View function logs
firebase functions:log
# View specific function logs
firebase functions:log --only aggregateDailyStatsMonitor Firestore usage in the Firebase Console:
- Read/write operations
- Storage usage
- Index usage
- Environment Variables: Never commit
.env.local - API Keys: Rotate keys regularly
- Security Rules: Test thoroughly before deployment
- Function Permissions: Use least privilege principle
- All inputs are validated in Cloud Functions
- Firestore security rules provide additional protection
- Type safety with TypeScript interfaces
# Deploy indexes
firebase deploy --only firestore:indexes# Check function logs
firebase functions:log
# Rebuild functions
cd functions && npm run build# Clear emulator data
firebase emulators:exec --only firestore,functions,auth "echo 'Cleared'"
# Restart emulators
npm run emulators- Verify Firebase project configuration
- Check API keys in
.env.local - Ensure Auth is enabled in Firebase Console
Enable debug logging:
// In your app
import { connectFirestoreEmulator } from 'firebase/firestore';
if (import.meta.env.DEV) {
connectFirestoreEmulator(db, 'localhost', 8080);
}- Use Indexes: All queries use proper indexes
- Batch Operations: Multiple writes in single batch
- Pagination: Limit query results
- Real-time Listeners: Efficient snapshot listeners
- Cold Start: Functions are optimized for quick startup
- Memory: Appropriate memory allocation
- Timeout: Reasonable timeout settings
- Retry Logic: Built-in error handling
- Monitor Logs: Check function logs weekly
- Update Dependencies: Monthly dependency updates
- Security Review: Quarterly security audit
- Performance Review: Monthly performance check
- Firestore: Automatic backups enabled
- Functions: Version control with Git
- Configuration: Document all settings
For technical support:
- Check Logs: Start with function logs
- Firebase Console: Check service status
- Documentation: Refer to Firebase docs
- Community: Firebase community forums
Status: ✅ Production Ready Last Updated: January 2025 Version: 1.0.0