SnapSolve is a SwiftUI iOS app that helps users snap a photo of an infrastructure issue (e.g., potholes, graffiti, broken streetlights), automatically enrich it with location context, and generate a structured report + recommended authority contact using an AI-backed backend.
This repo includes:
- iOS app (
SnapSolve/): SwiftUI, Camera + Map, Firebase Auth (Email/Password + Google). - Backend (
Backend/): Node.js/Express API with MongoDB persistence, Firebase Admin auth middleware, reverse geocoding, and email dispatch.
- Snap: capture an image in-app, optionally including GPS coordinates
- Analyze: backend returns a JSON result:
- issue description
- recommended department/authority
- contact email (when available)
- Submit: confirm and submit a “ticket” (protected via Firebase ID token)
- Track: view My Tickets (per-user)
- Explore: view reports on a map
Tip: Add screenshots/GIFs for extra polish:
docs/screenshots/01-camera.pngdocs/screenshots/02-analysis.pngdocs/screenshots/03-my-tickets.pngdocs/screenshots/04-map.png
- SwiftUI (UI + navigation)
- AVFoundation (camera capture)
- MapKit (map + annotations)
- Firebase Auth (email/password + Google Sign-In)
- Node.js + Express
- MongoDB + Mongoose (ticket/report storage)
- Firebase Admin (verify Firebase ID tokens)
- Google Maps Geocoding API (reverse geocode lat/lng → address metadata)
- Gemini (image + prompt → structured JSON analysis)
- Nodemailer (Gmail) (send report email)
- iOS captures image + (optional) location
- iOS calls
POST /api/analyzewith base64 image + coordinates - Backend reverse-geocodes coordinates and sends image+metadata to Gemini
- Backend returns
{ description, recommendation, email } - User confirms submission → iOS calls
POST /api/ticketswith Firebase ID token - Backend stores report in MongoDB and sends an email
Base path is mounted under /api in Backend/app.js.
-
POST
/api/analyze- body:
{ imageBase64, latitude?, longitude? } - returns:
{ description, recommendation, email? }
- body:
-
POST
/api/tickets(protected)- header:
Authorization: Bearer <Firebase ID Token> - body:
{ problem_description, recommendation, timestamp, email, latitude, longitude, imageBase64 } - returns: saved report document
- header:
-
GET
/api/tickets/my(protected)- header:
Authorization: Bearer <Firebase ID Token> - returns: list of reports created by the current user
- header:
-
GET
/api/tickets/all(public)- returns: list of all reports
-
GET
/api/tickets/locations(public)- returns:
{ id, latitude, longitude }[]
- returns:
- Xcode (iOS build/run)
- Node.js (backend)
- MongoDB (local or hosted)
- API keys:
- Google Maps Geocoding API key
- Gemini API key
- Email sending (optional for local): Gmail user + app password
- Firebase:
- iOS Firebase config (
GoogleService-Info.plist) - Firebase Admin service account (for backend token verification)
- iOS Firebase config (
From Backend/:
- Install dependencies
cd Backend
npm install- Create
.envfrom the template
cp env.example .env- Provide Firebase Admin credentials (choose one)
-
Option A (recommended): env var
- Set
FIREBASE_SERVICE_ACCOUNT_JSONin.envto the full service account JSON (as a single line).
- Set
-
Option B: local file (not committed)
- Place your Firebase service account at
Backend/serviceAccountKey.json(this path is gitignored). - Use
Backend/serviceAccountKey.example.jsonas a template.
- Place your Firebase service account at
- Start the API
npm run devBy default, the backend listens on http://localhost:4000.
- Open
SnapSolve.xcodeprojin Xcode - Ensure Firebase is configured:
SnapSolve/GoogleService-Info.plistshould match your Firebase project- enable Email/Password and Google Sign-In in Firebase Auth
- Point the app to your backend:
- update
baseURLinSnapSolve/BackendService.swifttohttp://localhost:4000(or your deployed URL)
- update
- Build & run on a simulator or device
SnapSolve/: iOS SwiftUI appBackend/: Node/Express API + MongoDB models