Case study · Published Android app
ARX: the app that decides how much weight to lift today
Android app for gym training, cardio and nutrition, published on Google Play. It logs every set, detects personal records live and suggests the load for the next session. I have built it on my own with AI assistants over 13 months, and 14 people use it.
The real app, in 80 seconds
The problem
People who train strength consistently note weights and reps in a notebook, a spreadsheet or a generic app. All three fail at the same thing: they do not tell you what to do today. Knowing whether to go up in weight means remembering the last session, how many reps you had left and whether it was a record.
What it does
- Fills in each exercise with the suggested load. When you mark the RIR (reps in reserve), the set is completed and the rest timer starts.
- Compares each set with your history and flags a record at that moment, not at the end.
- Using the RIR from the last set, it suggests increasing the load (+1.25 kg for upper body, +2.5 kg for lower body) or keeping it.
- Weekly streak, moving average of body weight and a regression-based forecast of when you will reach your goal.
User data, kept safe
If incremental sync fails, a full sync runs. Spending reads is better than losing data.
- Room is the source of truth and Firestore the mirror. The app works without signal, which is common in a basement gym.
- The incremental path never deletes. Only a full sync reconciles missing records, and only locally.
- Upsert, never REPLACE, in the food catalogue: a delete plus insert would trigger a cascading delete of the food diary.
- No destructive migrations: if a migration is missing, the app fails instead of wiping the user's database.
- Rules outside Android. Records, progression, streak and forecast live in pure objects tested in milliseconds. That is why they could be ported as they are to JavaScript for the demo.
Costs under control
The app runs on Firebase's free plan. A quota audit found 234,000 reads a month with 14 active users: there was headroom, but usage grew with every user. I added a read counter per domain and an incremental cursor for sessions. A sync pass went from about 2,800 reads to 52.
The AI inside the product (analysing a photo of a meal, summarising a workout) uses Gemini through Firebase AI Logic, with a fallback model if the main one fails.
What is real and what is demo
| Part | In the demo | Detail |
|---|---|---|
| Rules for records, progression, streak and forecast | Real | Ported to JavaScript with the same constants as the app. |
| History, profile and weigh-ins | Synthetic | “Alex Demo” profile generated with a fixed seed. |
| Interface | Synthetic | A recreation inspired by the app; it is not the Android app. |
| Sync, accounts, AI, GPS, nutrition and Health Connect | Not included | They exist in the app, outside the two-minute flow. |
Results
Limitations and next steps
- No UI tests: visuals are checked on the phone. Next step: instrumented tests for the critical flows.
- There is no 100% local mode without an account yet.
- Inherited debt of colours and strings not yet centralised, being replaced bit by bit.
Screenshots of the real app
Real recording of the app on a Pixel 8. The app interface is in Spanish.







