The S-Parking web dashboard is a vanilla JavaScript SPA deployed on Firebase Hosting , providing global CDN distribution, automatic SSL, and HTTP/2 support.
Prerequisites
Install Firebase CLI
npm install -g firebase-tools
Login to Firebase
This opens a browser window for Google authentication.
Initialize Project
cd web-dashboard
firebase init hosting
Select your existing Firebase project or create a new one.
Firebase Configuration
The S-Parking project uses the following firebase.json configuration:
{
"hosting" : {
"public" : "." ,
"ignore" : [
"firebase.json" ,
"**/.*" ,
"**/node_modules/**" ,
"gcp-functions/**" ,
"**/*.ps1" ,
"**/*.md" ,
".vscode/**"
],
"headers" : [
{
"source" : "**/*.html" ,
"headers" : [
{
"key" : "Cache-Control" ,
"value" : "no-cache"
}
]
},
{
"source" : "css/**" ,
"headers" : [
{
"key" : "Cache-Control" ,
"value" : "public, max-age=86400"
}
]
},
{
"source" : "js/**" ,
"headers" : [
{
"key" : "Cache-Control" ,
"value" : "public, max-age=86400"
}
]
},
{
"source" : "assets/**" ,
"headers" : [
{
"key" : "Cache-Control" ,
"value" : "public, max-age=604800"
}
]
}
]
}
}
Configuration Breakdown
Public Directory
Serves files from the current directory (web-dashboard/). All HTML, CSS, JS, and assets are in the root.
Ignored Files
"ignore" : [
"firebase.json" ,
"**/.*" ,
"**/node_modules/**" ,
"gcp-functions/**" ,
"**/*.ps1" ,
"**/*.md" ,
".vscode/**"
]
Excludes backend functions, config files, and development artifacts from deployment.
S-Parking implements a multi-tier caching strategy for optimal performance:
HTML Files (No Cache)
CSS/JS (1 Day Cache)
Assets (1 Week Cache)
{
"source" : "**/*.html" ,
"headers" : [{
"key" : "Cache-Control" ,
"value" : "no-cache"
}]
}
Resource Type Cache Duration Rationale HTML No cache Ensures users always get the latest version CSS/JS 24 hours (86400s) Balance between performance and update frequency Assets 7 days (604800s) Static images/icons rarely change
The no-cache directive for HTML files forces browsers to revalidate with the server on each request. This ensures users receive updated JavaScript/CSS references immediately after deployment.
Deployment Process
Standard Deployment
Build and Deploy
cd web-dashboard
firebase deploy --only hosting
This uploads all files to Firebase Hosting and applies cache headers.
Verify Deployment
Firebase CLI outputs the hosting URL: ✔ Deploy complete!
Hosting URL: https://your-project.web.app
Test Live Site
Open the URL in a browser and verify:
Dashboard loads correctly
Google Maps renders
Real-time parking data appears
Preview Deployment (Testing)
Test changes before going live:
firebase hosting:channel:deploy preview
This creates a temporary URL like https://your-project--preview-abc123.web.app valid for 7 days.
Preview channels are publicly accessible. Do not deploy sensitive data or credentials.
Custom Domain Setup
Add Custom Domain
firebase hosting:sites:create your-custom-domain
Or use Firebase Console → Hosting → Add custom domain.
Verify Domain Ownership
Add TXT record to your DNS provider: TXT @ firebase=your-project-id
Configure DNS Records
Add A records pointing to Firebase: A @ 151.101.1.195
A @ 151.101.65.195
Wait for SSL Provisioning
Firebase automatically provisions a free SSL certificate. This may take 24-48 hours.
Update Configuration Before Deploy
Before deploying, update API endpoints in js/config/config.js:
export const CONFIG = {
DEBUG: false , // Disable debug logs in production
GOOGLE_MAPS_API_KEY: "YOUR_PRODUCTION_API_KEY" ,
GOOGLE_MAPS_ID: "YOUR_MAP_ID" ,
// Update with deployed Cloud Run URLs
GET_STATUS_API_URL: "https://get-parking-status-[hash].run.app" ,
RESERVATION_API_URL: "https://reserve-parking-spot-[hash].run.app" ,
RELEASE_API_URL: "https://release-parking-spot-[hash].run.app" ,
CREATE_SPOT_URL: "https://create-parking-spot-[hash].run.app" ,
DELETE_SPOT_URL: "https://delete-parking-spot-[hash].run.app" ,
GET_ZONES_URL: "https://get-zones-[hash].run.app" ,
MANAGE_ZONES_URL: "https://manage-zones-[hash].run.app" ,
GET_HISTORY_URL: "https://get-occupancy-history-[hash].run.app" ,
FIREBASE: {
apiKey: "YOUR_FIREBASE_KEY" ,
authDomain: "your-project.firebaseapp.com" ,
projectId: "your-project-id" ,
storageBucket: "your-project.appspot.com" ,
messagingSenderId: "123456789" ,
appId: "1:12345:web:abcdef"
}
};
NEVER commit API keys to version control! Copy config.example.js to config.js and add config.js to .gitignore.
Rollback to Previous Version
Firebase retains deployment history:
# List all releases
firebase hosting:releases:list
# Rollback to specific version
firebase hosting:rollback
Select the target release from the interactive menu.
Enable Compression
Firebase Hosting automatically compresses assets with gzip and Brotli . No configuration needed.
Verify Compression
curl -H "Accept-Encoding: gzip" -I https://your-project.web.app/js/map/core.js
Response should include:
Preconnect to External Services
Add to index.html <head>:
<!-- Preconnect to Google Maps API -->
< link rel = "preconnect" href = "https://maps.googleapis.com" >
< link rel = "preconnect" href = "https://maps.gstatic.com" crossorigin >
<!-- Preconnect to Cloud Run endpoints -->
< link rel = "preconnect" href = "https://[region]-[project].run.app" >
Monitoring and Analytics
View Hosting Metrics
firebase hosting:channel:list
Or use Firebase Console → Hosting → Usage to see:
Bandwidth usage
Request count
Geographic distribution
Integrate Google Analytics
Add to index.html:
<!-- Google Analytics 4 -->
< script async src = "https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX" ></ script >
< script >
window . dataLayer = window . dataLayer || [];
function gtag (){ dataLayer . push ( arguments );}
gtag ( 'js' , new Date ());
gtag ( 'config' , 'G-XXXXXXXXXX' );
</ script >
Troubleshooting
Issue: “Error: HTTP Error: 403, Permission Denied”
Solution: Re-authenticate Firebase CLI:
firebase logout
firebase login --reauth
Issue: Stale cached content after deployment
Solution: HTML files use no-cache, but hard refresh to clear browser cache:
Chrome/Edge : Ctrl+Shift+R (Windows) or Cmd+Shift+R (Mac)
Firefox : Ctrl+F5 (Windows) or Cmd+Shift+R (Mac)
Issue: 404 errors on direct URL access
Solution: Add rewrites to firebase.json for SPA routing:
"rewrites" : [
{
"source" : "**" ,
"destination" : "/index.html"
}
]
Issue: CORS errors when calling Cloud Run
Solution: Ensure Cloud Run functions include CORS headers. S-Parking functions use the cors package:
const cors = require ( 'cors' )({ origin: true });
exports . yourFunction = ( req , res ) => {
cors ( req , res , () => {
// Your function logic
});
};
CI/CD Integration
Automate deployments with GitHub Actions:
.github/workflows/deploy.yml
name : Deploy to Firebase Hosting
on :
push :
branches :
- main
jobs :
deploy :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v3
- uses : FirebaseExtended/action-hosting-deploy@v0
with :
repoToken : '${{ secrets.GITHUB_TOKEN }}'
firebaseServiceAccount : '${{ secrets.FIREBASE_SERVICE_ACCOUNT }}'
channelId : live
projectId : your-project-id
Generate a service account key in Firebase Console → Project Settings → Service Accounts, then add it as a GitHub secret.
Next Steps
Configure Cloud Run Deploy backend services to Google Cloud Run
Environment Variables Manage API keys and configuration
Flash ESP32 Firmware Deploy IoT sensors with production endpoints