JSJorge Sebastián Soriano ES

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.

Where it's used
Google Play · 14 active users
Status
Published on Google Play · version 5.15
My role
Product, technical direction, testing, publishing and maintenance
Technologies
Kotlin, Jetpack Compose, Room, Firestore, Hilt, Health Connect, Gemini
The real ARX app: set by set with RIR
Real recording of the app on a Pixel 8.

The real app, in 80 seconds

Real recording of the app on a Pixel 8: session set by set, summary on saving, history, nutrition and body weight.

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

Non-negotiable rule

If incremental sync fails, a full sync runs. Spending reads is better than losing data.

Compose UIViewModelsRoomsource of truthOrchestratorsequencing and waitsSync per domainfull or incrementalFirestorecloud mirror
  • 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

PartIn the demoDetail
Rules for records, progression, streak and forecastRealPorted to JavaScript with the same constants as the app.
History, profile and weigh-insSynthetic“Alex Demo” profile generated with a fixed seed.
InterfaceSyntheticA recreation inspired by the app; it is not the Android app.
Sync, accounts, AI, GPS, nutrition and Health ConnectNot includedThey exist in the app, outside the two-minute flow.

Results

14active usersSeptember 2026 audit
2,800 → 52reads per syncmeasured on the phone
5/5 → 0/5cold start failuresreproduced and verified in release

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.

Home: weekly streak, today's macros and last workout
Home: weekly streak, today's macros and last workout
Choose strength, cardio or manual activity
Choose strength, cardio or manual activity
Set by set with weight, reps and RIR
Set by set with weight, reps and RIR
Achievement unlocked on saving: 9.7 t lifted
Achievement unlocked on saving: 9.7 t lifted
History: one session in detail with its RIR
History: one session in detail with its RIR
Nutrition: today's calories and macros
Nutrition: today's calories and macros
Food rating when adding it
Food rating when adding it
Weight statistics and trend
Weight statistics and trend