Your garage, in your pocket — no backend, no subscription, no ads.
A cross-platform vehicle service tracker built with React Native + Expo. Track maintenance, documents, and inventory for every car, bike, or scooter you own — entirely on-device.
- Why ServiceMyRide?
- Features
- Requirements
- Setup
- Run
- Google Sign-In & Drive backup
- Project structure
- Customizing maintenance intervals
- Contributing
- License
Most vehicle-maintenance apps assume a cloud account, a subscription, or a fleet of trackers reporting telemetry. ServiceMyRide assumes none of that: everything lives in a single JSON document on your device, so it works fully offline from the first launch. Signing in with Google is optional and only unlocks backup/sync to a private folder in your own Drive — your data is never sent anywhere else.
| 🚗 Multi-vehicle garage | Cars, motorcycles, electric scooters, or custom types — with odometer, make/model/year, and plate. |
| 🔧 Maintenance tracking | Pick from presets (oil, filters, brakes, coolant, spark plugs, chain, tires, battery…) filtered by vehicle type, or add your own custom task. Every log stores date, odometer, cost, and notes. |
| 🟢 Smart due status | Computes OK / Soon / Overdue per task from both a time interval and an odometer interval, and surfaces alerts on the home dashboard. |
| 📦 Parts inventory | Track parts you've bought but not installed yet — category, quantity, cost, linked vehicle, and a mark-used/in-stock toggle, with total stock value. |
| 📄 Documents & due dates | Insurance, registration/license, inspection, road tax, warranty — with an auto-scheduled expiry reminder N days ahead. |
| ⏰ Reminders | One-off or repeating (daily/weekly/monthly) local notifications, with quick presets like "charge the battery." |
| ☁️ Google sign-in + Drive backup | Back up all your data to a private folder in your own Google Drive and sync it across devices. Works on iOS and Android. |
All data is stored locally via AsyncStorage as a single JSON document (easy to migrate to SQLite later). Google Drive is used only for backup/sync — the app works fully offline without signing in.
- Node.js 18+ and npm
- Expo CLI (
npm i -g expooptional —npx expoworks without a global install) - A development build for notifications on device, since they rely on a native module that won't run in Expo Go.
git clone https://github.com/mnimonic/ServiceMyRide.git
cd ServiceMyRide
npm installAndroid / iOS with native modules (notifications):
# one-time: create a dev build
npx expo install expo-dev-client
npx expo prebuild
npx expo run:android # or: npx expo run:ios (needs macOS + Xcode)Then npm start and open the dev build.
Note
expo-notifications doesn't work in Expo Go — use a dev build to test reminders.
How sync works
| Action | Effect |
|---|---|
| Sign in | Pulls any existing cloud backup, merges it with local data, and pushes the result back. |
| Sync now (merge) | Same pull → merge → push; safe to run on multiple devices (union of records by id, local wins on conflicts). Runs automatically once when the Garage tab opens. |
| Back up ↑ | Overwrites the cloud copy with this device's data. |
| Restore ↓ | Overwrites this device's data with the cloud copy. |
If an access token expires (401), the app signs you out so you can re-authenticate. Adding long-lived silent refresh would require a backend to exchange the OAuth refresh token — the current setup deliberately keeps everything client-side.
Platform differences
iOS uses expo-auth-session for "Login with Google"; Android uses @react-native-google-signin/google-signin (a native Play Services flow), because Google no longer supports custom-scheme redirects for Android OAuth clients — the browser-redirect approach expo-auth-session relies on cannot work there anymore.
All platforms use the Google Drive REST API for backup. Backups live in Drive's appDataFolder — a hidden, per-app folder — so the app only requests the narrow drive.appdata scope, and your backup never clutters your visible Drive.
Step-by-step Google Cloud setup
- Create a Google Cloud project → https://console.cloud.google.com
- OAuth consent screen: configure it (External is fine for personal use), add your email as a test user, and under Data access → Add or remove scopes add
.../auth/userinfo.email,.../auth/userinfo.profile, and (search "Drive", from the Google Drive API).../auth/drive.appdata. - Enable the Google Drive API under APIs & Services → Library — the
drive.appdatascope won't show up in step 2 until this is enabled. - Create credentials → OAuth client IDs, one per platform you target:
- Web application — required for Android: the native sign-in library authenticates the app via Play Services (using the Android client below) but is configured with the Web client id. No JavaScript origin or redirect URI needs to be added since this app never runs the browser-based OAuth flow.
- iOS — bundle id
com.servicemyride.app. - Android — package
com.servicemyride.app+ the SHA-1 of your signing key (debug keystore for local dev-client builds:keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android; production key viaeas credentials).
- Copy
.env.exampleto.envand paste the client IDs:EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID=... EXPO_PUBLIC_GOOGLE_IOS_CLIENT_ID=... EXPO_PUBLIC_GOOGLE_ANDROID_CLIENT_ID=... - Rebuild (
npx expo prebuildthennpx expo run:android/run:ios— the Android sign-in library is a native module, so a Metro-only restart isn't enough after first install). Open the Account tab and tap Continue with Google.
[!NOTE] Like notifications, Google Sign-In needs a development build on device — it does not work in Expo Go.
app/
_layout.js Root stack + AppProvider + AuthProvider
(tabs)/
_layout.js Bottom tab navigator
index.js Garage: vehicle list + dashboard alerts + auto-sync
reminders.js Reminders (local notifications)
inventory.js Parts inventory
documents.js Insurance / registration / due dates
account.js Google sign-in + Drive backup/restore/sync
vehicle/[id].js Vehicle detail: maintenance history, editing
src/
constants/index.js Colors, vehicle types, maintenance presets, doc types
context/
AppContext.js Global data state + CRUD wrappers
AuthContext.js Google auth, token storage, Drive sync logic
refreshBridge.js Lets AuthContext trigger an AppContext reload post-sync
storage/db.js AsyncStorage repository (+ dump/replaceAll/mergeAll)
components/ui.js Reusable UI (Card, Button, Field, Chip, Sheet, Badge…)
utils/
notifications.js expo-notifications scheduling
googleDrive.js Google Drive REST API (appDataFolder backup)
helpers.js Dates + maintenance-status computation
Edit src/constants/index.js → MAINTENANCE_PRESETS. Each entry has:
intervalKm— odometer-based interval (ornull)intervalMonths— time-based interval (ornull)appliesTo— which vehicle types show this task
Issues and pull requests are welcome. There's no test suite, lint config, or build/typecheck script in this repo yet, so please:
- Keep changes scoped and test them by actually running the app on a dev build (notifications require a native module, so Expo Go isn't enough).
- Follow the existing patterns — see
src/storage/db.jsfor the data layer andsrc/components/ui.jsfor shared UI primitives — rather than introducing new ones for the same purpose. - Open an issue first for larger changes (new record types, new sync behavior) so the approach can be discussed before you invest the time.
MIT © George Danilopoulos