Gamified street-camera-spotting platform. For educational purposes only.
CCatcher lets you tag street cameras (CCTV / IP / Flock) on a map, earn XP for your finds, form teams, and climb global leaderboards.
-
Tag cameras with type, view-angle wedge, tags, and a comment

-
Edit/delete your own entries (long-press), public or private visibility

-
Teams: create, invite, join, leave, dissolve, appoint admins

-
Global user + team leaderboards and ranks
-
Dark, pixel-styled UI
app/— Expo Router screens ((auth)and(tabs))src/firebase.ts— Firebase initsrc/AuthContext.tsx— auth state + sign up/in/outsrc/firestore.ts— all database reads/writes + scoringsrc/geo.ts— view-wedge math (GeoJSON for MapLibre)src/theme.ts— design tokensfirestore.rules— security rules (publish these in the Firebase console)
MapLibre is a native module, so the app runs as a development build (
npx expo run:android), not in Expo Go.
git clone https://github.com/planmarks/<repo>.git
cd <repo>
npm installThe committed src/firebase.ts points at the maintainer's Firebase project.
Firebase web config is not a secret (it ships inside every built app), but to
run your own backend:
- Create a Firebase project (Spark/free plan) at https://console.firebase.google.com.
- Add a Web app and copy its config into
src/firebase.ts. - Authentication → Sign-in method → enable Email/Password.
- Firestore Database → Create database, then paste
firestore.rulesinto Firestore → Rules → Publish.
npx expo run:android # builds + installs the dev client, then hot-reloads JSnpm install -g eas-cli
eas login
eas build:configure # Android
eas build -p android --profile preview # installable .apk (sideload / testers)
eas build -p android --profile production # signed .aab (Google Play upload)Profiles live in eas.json. Bump android.versionCode (in app.json) for each
Play upload — the production profile auto-increments it.
Because the app is open source and the client config is public, the real security boundary is the backend, not the source:
- Firestore rules (
firestore.rules) gate all data access — keep them published and tight. - Restrict the Firebase API key in Google Cloud Console → APIs & Services → Credentials (limit to your Android app's package + SHA-1, and to the APIs you use).
- Consider enabling Firebase App Check to block requests from outside your app.
- Scoring is client-side (no Cloud Functions on the free plan), so it is not tamper-proof — fine for an educational MVP, not for competitive stakes.
- The map currently uses raw OpenStreetMap tiles; for a high-traffic deployment switch to a tile provider that permits app usage (e.g. MapTiler) to respect OSM's tile policy.
See PRIVACY_POLICY.md.
MIT.
You can contact me either via e-mail aleks@planmarks.eu or via Instagram @papathought
