# Install Firebase CLI if not already installed
npm install -g firebase-tools
# Ensure you're in the project directory
cd /home/flavio/Develop/RemoteJobsServerless# Start all emulators (Firestore + Functions)
firebase emulators:start
# Or start specific emulators
firebase emulators:start --only functions,firestoreThe emulators will start on:
- Firestore Emulator: http://localhost:8080
- Functions Emulator: http://localhost:5001
- Emulator UI: http://localhost:4000
Since Cloud Scheduler isn't available in the emulator, you need to manually trigger the scheduled function:
# In a new terminal, start the functions shell
firebase functions:shell
# Then in the shell, run:
updateRemoteJobsCache()- Open http://localhost:4000
- Navigate to Functions tab
- Find
updateRemoteJobsCache - Click "Run function"
# This simulates the Cloud Scheduler trigger
curl -X POST \
http://localhost:5001/YOUR-PROJECT/us-central1/updateRemoteJobsCache \
-H "Content-Type: application/json" \
-d '{}'# Call the HTTP function endpoint
curl http://localhost:5001/YOUR-PROJECT/us-central1/getRemoteJobs
# Or open in browser
# http://localhost:5001/YOUR-PROJECT/us-central1/getRemoteJobs- Open Firestore Emulator UI: http://localhost:4000/firestore
- Look for the
remoteJobscollection - Check the
latestdocument - Verify structure:
jobsarray exists and has job objectsmetadataobject contains:lastUpdatedtimestampjobCountnumbersourcesobject with per-source statisticsupdateDurationMsnumber
firebase emulators:startWait until you see:
✔ All emulators ready!
Using functions shell:
# In new terminal
firebase functions:shell
# In shell
updateRemoteJobsCache()Expected output:
Starting scheduled job cache update...
Fetching https://remoteok.io/api - attempt 1
Fetching https://weworkremotely.com/... - attempt 1
...
Cache updated successfully: XXX jobs from 5 sources
Update took XXXXXmsOpen http://localhost:4000/firestore and verify data structure.
curl http://localhost:5001/YOUR-PROJECT/us-central1/getRemoteJobs | jqExpected response:
{
"jobs": [
{
"id": "...",
"company": "...",
"position": "...",
"date": "...",
"image": { "uri": "..." },
"description": "...",
"url": "...",
"tags": ["..."],
"source": "..."
}
],
"metadata": {
"lastUpdated": "2024-12-03T23:00:00.000Z",
"jobCount": 150,
"cacheAgeMinutes": 5,
"cacheStatus": "cached"
}
}To test the fallback when cache doesn't exist:
- Delete the Firestore document via emulator UI
- Call the HTTP endpoint
- Should see
"cacheStatus": "live-fetch"in response - Cache document should be recreated
-
Trigger Initial Cache Update
gcloud scheduler jobs run firebase-schedule-updateRemoteJobsCache --location=us-central1 -
Wait 30 seconds for function to complete
-
Check Firestore
- Open Firebase Console
- Navigate to Firestore Database
- Verify
remoteJobs/latestdocument exists
-
Test HTTP Endpoint
curl https://YOUR-REGION-YOUR-PROJECT.cloudfunctions.net/getRemoteJobs
-
Verify Response Time
- Should be < 200ms (vs previous 10-30s)
# Watch function logs in real-time
firebase functions:log --only updateRemoteJobsCache
# Check for any errors
firebase functions:log | grep ERROR-
Scheduled Function Success Rate
- Should run every hour
- Check logs for successful updates
- Verify job counts are reasonable
-
HTTP Function Response Time
- Should be < 100ms for cached responses
- Check
cacheAgeMinutesin response
-
Source Success Rates
- Check metadata.sources in Firestore
- Some sources may occasionally fail (acceptable)
- Scheduled function runs every hour
- Cache is updated successfully
- HTTP requests return cached data quickly
- All 5 sources provide data
Expected: Fast responses, fresh data, no errors
- One or more job sources fail
- Scheduled function continues with available data
- HTTP requests still work with partial data
Expected: Reduced job count, warnings in logs, but system continues working
- All job sources fail temporarily
- Scheduled function logs errors but doesn't crash
- HTTP requests serve stale cached data
Expected: Old cache data served, errors logged, system remains available
- Cache document deleted or expired
- HTTP request triggers fallback fetch
- New cache created for next request
Expected: Slower first request, subsequent requests fast
- Multiple concurrent HTTP requests
- All read from same Firestore document
Expected: Consistent fast responses, no rate limiting
- Scheduled Function Execution: 20-60 seconds
- HTTP Function Response Time: < 100ms
- Cache Update Frequency: Every 60 minutes
- Job Count: 100-500 jobs (varies by day)
# Time the HTTP request
time curl https://YOUR-REGION-YOUR-PROJECT.cloudfunctions.net/getRemoteJobs > /dev/null
# Should show:
# real 0m0.150s (under 200ms total)Functions not starting:
# Clear emulator data
firebase emulators:start --export-on-exit=./emulator-data --import=./emulator-dataPort conflicts:
# Change ports in firebase.json
{
"emulators": {
"functions": { "port": 5002 },
"firestore": { "port": 8081 }
}
}Scheduled function timing out:
- Check internet connectivity
- Some sources may be slow (normal)
- Increase timeout if needed (max 540s for scheduled functions)
HTTP function returning 500:
- Check Firestore access
- Verify cache document exists
- Review function logs
# Stop emulators
# Press Ctrl+C in the terminal running emulators
# Remove emulator data (optional)
rm -rf .firebase/- Deploy to production (see DEPLOYMENT.md)
- Set up monitoring alerts
- Update client applications to use new response format
- Monitor costs and performance