TrackPix — Data Privacy Policy
1. Introduction
TrackPix is a native Android photo editor for runners. It overlays a personalised achievement stats card onto a photo and uses on-device AI to cut out the person so they appear in front of the card. Your privacy is built into the app’s architecture: most processing happens entirely on your device, data is never sold or rented, and the only off-device telemetry requires your explicit consent.
This policy describes what information TrackPix accesses, why, how it is stored, and what controls you have.
2. Information We Access
2.1 Photos and Media
| What | How |
|---|---|
| Photos you select from your gallery or capture with the camera | Loaded on-device only for editing and rendering. |
| The exported composition (stats card + photo) | Written to your device’s default gallery folder (Pictures/) on Save. |
| Intermediate render cache files | Written to the app-private cache (/data/data/…/cache/) during export and deleted when the OS purges the cache. |
Key guarantee: photos are processed and composited 100 % on-device. They are never uploaded or transmitted by TrackPix. If you choose to save, share, or copy an exported composition, Android may make that exported image available to the gallery, destination app, or system clipboard you select.
2.2 Running Activity Data (Strava)
When you choose to Connect with Strava, TrackPix fetches your running activities from the TrackPix backend (trackpix.app), which holds the data your Strava account has already authorised that service to access. The fields retrieved are:
- Activity name, sport type, and start date
- Distance, moving time, average pace, elevation gain
- Average heart rate and calories (when recorded by your device)
- GPS route summary polyline (for map rendering)
- Computed training metrics: training load, effort pace, estimated VO₂max, and predicted race finish times
This data is cached locally on your device (plain JSON, app-private storage) so the app launches instantly without a round-trip. The cache is cleared when you disconnect your Strava account or uninstall the app.
Activities are never shared with any third party beyond the TrackPix backend and (opt-in) crash diagnostics described below.
2.3 User-Added Tags and Feedback
You may optionally attach post-run tags to an activity — Feeling, Energy, and RPE (perceived effort 1–10). These are stored locally first, then synced to the TrackPix backend so they persist across reinstalls. They are tied to your activity record, not to any advertising identifier.
2.4 Session Tokens
After a successful Strava OAuth connect, the TrackPix backend issues a JWT access token and a rotating refresh token. These are stored via react-native-keychain, which persists them in the Android Keystore / EncryptedSharedPreferences (hardware-backed where the device supports it), not a plain file. They are used solely to authenticate requests to the TrackPix backend and are cleared from the Keystore when you disconnect your account.
Note: older builds stored tokens in a plaintext file (DocumentDirectory/trackpix-tokens.json). Current versions migrate any such legacy file into the Keystore on first launch and delete the plaintext copy; the file is no longer written going forward.
2.5 Map Tiles
The Dashboard and Activity Detail screens display your GPS route on a map. Basemap tiles are fetched from CARTO (basemaps.cartocdn.com) — a CDN that renders OpenStreetMap data. Fetching a tile reveals your IP address to CARTO’s CDN, as with any web request. No activity data, user ID, or personal information is sent with tile requests. Tiles are cached locally to avoid redundant fetches.
2.6 Diagnostics and Analytics (Opt-in Only)
TrackPix integrates Firebase Crashlytics and Firebase Analytics. Collection is disabled by default at build time (firebase.json → *_auto_collection_enabled = false) and is only enabled if you grant consent through the in-app prompt (which appears once, after your first export).
What is collected (if you consent):
| Category | Examples |
|---|---|
| Screen views | Which tab was visited (enum only — never user content) |
| Funnel events | connect_started, connect_succeeded, tracklog_exported |
| Activity counts | Number of activities imported (integer — no activity detail) |
| Crash logs | Stack traces, non-fatal JS errors, device/OS enum |
| Device identifiers | Android Advertising ID (GAID) and SSAID — collectible by the bundled Firebase Analytics SDK’s default configuration once you consent (see note below) |
Advertising ID note: the bundled Firebase Analytics SDK ships with Google’s default data-collection settings for the Advertising ID (GAID) and Android SSAID left on. TrackPix shows no ads, runs no ad network, and does not use these identifiers for advertising, attribution, or personalization — but because firebase.json does not override Firebase’s defaults, the SDK is technically capable of collecting them once you grant telemetry consent. This is disclosed here for completeness and reflected in the app’s Play Console Data Safety declaration under “Device or other IDs.”
What is never collected (enforced in services/telemetry.ts):
- Photo content or pixel data
- GPS coordinates or route geometry
- Strava IDs, access tokens, or refresh tokens
- Activity names, distances, paces, HR, or any fitness metric
- Any free-text you type (feelings notes)
- Any use of device/advertising identifiers for ads, attribution, or cross-app tracking (see the Advertising ID note above for the technical collection capability disclosure)
You can withdraw consent at any time in Settings → Privacy. Revoking consent immediately disables both Crashlytics and Analytics collection.
3. Permissions
| Permission | Why it is needed | Optional? |
|---|---|---|
INTERNET | Strava OAuth, activity sync with the TrackPix backend, Firebase telemetry (opt-in), map tile fetches | No (core feature) |
CAMERA | Taking a new photo to use as the card background | Yes — only requested if you tap “Take a Photo” |
READ_MEDIA_IMAGES | Selecting a photo from your gallery | Yes — only requested when you open the photo picker |
WRITE_EXTERNAL_STORAGE | Saving the exported PNG to your gallery (Android 10 and below only) | Yes — only when you tap Save |
No permission is requested pre-emptively at launch. Each permission request appears at the point of first use, with a clear in-context explanation. Declining any permission disables the corresponding feature but does not affect other features. You can revoke permissions at any time in Android Settings → Apps → TrackPix → Permissions.
Permissions bundled by embedded SDKs. The installed app’s manifest also includes the following, added automatically by dependencies at build time. None of these are requested from you at runtime, none prompt a permission dialog, and none unlock a TrackPix feature:
| Permission | Source | Purpose |
|---|---|---|
READ_EXTERNAL_STORAGE | Filesystem library (@dr.pogodin/react-native-fs) | Legacy storage compatibility on older Android versions |
ACCESS_NETWORK_STATE, WAKE_LOCK | Firebase SDK | Standard connectivity checks / background retry housekeeping |
READ_PHONE_STATE | Google Play services (Firebase Analytics dependency) | Declared by the underlying Play services library; TrackPix never calls a phone-state API |
com.google.android.gms.permission.AD_ID, ACCESS_ADSERVICES_ATTRIBUTION, ACCESS_ADSERVICES_AD_ID | Firebase Analytics dependency | See §2.6’s Advertising ID note — present because of the bundled SDK, not used by TrackPix for ads |
BIND_GET_INSTALL_REFERRER_SERVICE | Google Play services | Standard Play Store install-attribution hook bundled with Play services; unused by TrackPix |
4. Data Storage and Retention
| Data | Location | Retention |
|---|---|---|
| JWT access + refresh tokens | Android Keystore / EncryptedSharedPreferences (via react-native-keychain) | Until you disconnect your account or uninstall |
| Cached activities | App-private file (DocumentDirectory) | Until you disconnect or uninstall |
| UI state flags (onboarding seen, tour completed, consent given) | App-private file (DocumentDirectory) | Until you uninstall |
| Race goal | App-private Zustand store snapshot | Until you change it or uninstall |
| Render cache (temp PNGs) | App cache (CacheDirectory) | Cleared automatically by the OS |
| Route map tile cache | App cache (CacheDirectory) | Cleared automatically by the OS |
| Exported composition | Device gallery (Pictures/) | You control this — delete it from your gallery at any time |
| Firebase crash + analytics logs | Google Firebase servers | 90 days (Firebase default), only if you consented |
The TrackPix backend (trackpix.app) stores:
- Your Strava OAuth tokens (access + refresh), encrypted at rest
- Your imported activity records and any feedback tags you submit
- No photos
You can request deletion of your backend data by emailing vnengineers.ltd@gmail.com with the subject “Data deletion request”. We will process the request within 30 days.
5. Third-Party Services
| Service | Purpose | Data shared | Privacy policy |
|---|---|---|---|
| Strava (via TrackPix backend) | Activity data source | OAuth authorisation; activity data is stored on the backend, not sent to Strava from the app | https://www.strava.com/legal/privacy |
TrackPix backend (trackpix.app) | Strava OAuth, activity sync, training metrics | JWT tokens, activity data, feedback tags | Governed by this policy |
| Google Firebase (opt-in) | Crash reporting + usage analytics | Non-identifying enums / counts, plus Advertising ID/SSAID per the bundled SDK’s defaults (see §2.6) | https://firebase.google.com/support/privacy |
| CARTO / OpenStreetMap | Basemap tiles | IP address (standard CDN request) | https://carto.com/privacy |
Future service (not yet active): a future release will add AI-powered coaching summaries. When enabled, aggregated (non-photo) activity metrics will be sent to OpenAI. This feature will be gated behind a separate opt-in prompt, and this policy will be updated before that release ships.
6. Data Sharing
TrackPix does not sell, rent, or trade personal information.
Data is shared only in the following circumstances:
- TrackPix backend — activity data and feedback tags to power sync and metrics (see §2.2–2.3).
- Firebase — anonymised diagnostics, only if you consented (see §2.6).
- CARTO — your IP address is exposed when fetching map tiles, as with any HTTP request.
- Legal obligation — if required by applicable law, court order, or government authority.
7. Data Security
- All network communication with the TrackPix backend uses HTTPS / TLS.
- Session tokens are stored in the Android Keystore (
react-native-keychain), not a plaintext file. - Other app-private files (activity cache, UI state) are stored in the app’s sandboxed private directory, inaccessible to other apps (standard Android sandboxing).
- The app declares
android:allowBackup="false", so private app data is excluded from Android cloud backups. - Photo content is not written to locations accessible to other apps except when you intentionally save the exported composition to the gallery, share it through the Android share sheet, or copy it to the system clipboard.
8. Children’s Privacy
TrackPix is not directed at children under 13 years of age and does not knowingly collect personal data from children. If you believe a child has provided us with personal information, please contact us at vnengineers.ltd@gmail.com and we will promptly delete it.
9. Your Controls
| Action | How |
|---|---|
| Revoke camera or gallery permission | Android Settings → Apps → TrackPix → Permissions |
| Revoke or grant analytics / crash reporting consent | TrackPix → Settings → Privacy |
| Disconnect Strava and clear all cached activity data | TrackPix → Settings → Disconnect |
| Delete exported photos | Your device Gallery app |
| Delete all app data (tokens, cache, UI flags) | Android Settings → Apps → TrackPix → Storage → Clear Data |
| Request deletion of backend data | Email vnengineers.ltd@gmail.com |
| Uninstall the app | Android Settings → Apps → TrackPix → Uninstall |
10. Changes to This Policy
When this policy changes materially (new data types collected, new third parties, or new off-device transmissions), we will update the “Last updated” date at the top of this document and publish the updated version on the app’s Play Store listing. Continued use of the app after the update date constitutes acceptance of the revised policy.