AI Doesn't Do Math: How I Built a Budgeting App

A computer science student built a budgeting app in Flutter, letting a pure Dart engine do the math while AI only explains.
A Flutter developer built the Android budgeting app Budget Lover. Its core isn't tracking expenses but delivering a daily "safe-to-spend" amount by subtracting bills, subscriptions, savings, and a buffer from the balance, then dividing by days until payday. All calculation lives in a pure Dart engine layer; AI only explains and never does arithmetic, with facts computed locally before being sent to Gemini. API keys go through Firebase AI Logic with App Check, and the app includes receipt scanning, subscription detection, trip budgets, 15 languages, and more.
Most budgeting apps answer the same question: How much have I spent? But what a computer science student really wanted to ask was: How much can I spend today without regretting it at the end of the month?
To solve this, he single-handedly developed Budget Lover, an Android app (Flutter + Firebase + Gemini). The core of this app isn't tracking—it's delivering a single number: the daily "safe-to-spend" amount, plus an AI advisor you can follow up with. According to the author's development log, the project hasn't been released yet, and all testing was done on an emulator with demo data.

One Number: Safe-to-Spend Amount
The app's logic is straightforward: take the account balance and subtract all the money already "spoken for" before the next payday.
// Simplified engine logic
safe = balance
- upcomingBills
- subscriptions
- plannedPayments
- savingsContribution
- safetyBuffer;
dailyAllowance = safe > 0 ? safe / daysUntilPayday : 0;
What's left is the portion you can freely spend. Divide that by the number of days until the next payday, and you get the daily allowance. The actual version also handles monthly budget caps, travel, debt repayment, and subscriptions automatically detected from historical records, but the core shape stays the same.
The author put all of this in a pure Dart "engine" layer with no Flutter or Firebase dependencies. He calls this the single best decision of the project—the engine runs unit tests in milliseconds, while the app is full of edge cases: end of month, payday shifts, bills due tomorrow.
AI Explains, Code Calculates
The author wanted an advisor that could answer "Can I afford this 80-euro thing?" But he was well aware that language models are unreliable at arithmetic and happily fabricate plausible-sounding numbers.
So, AI never does math.
When a user asks a question, the app first computes the relevant facts locally: the current safe-to-spend amount, the new value after the purchase, the new daily allowance, upcoming bills. Only with these facts in hand does it send the question—along with the numbers—to Gemini, asking it to explain the result in plain language.
The advisor's response in the screenshot ("New safe-to-spend amount is 290 euros, conclusion: tight") is based on numbers produced by the engine. The model's job is tone and explanation, not accounting. A side benefit: the facts contain only totals and category names, so the model never needs to see individual transactions.
The same engine also powers a "What if...?" simulator. It runs the calculation twice: once with real data, once with a change applied (spend 150 euros, cancel a subscription, reduced income), then shows the difference. No data is ever saved.
So-called "probabilistic models" refer to the fact that when a large language model generates a response, it doesn't retrieve answers from a deterministic fact base—it predicts the next token one by one according to a probability distribution. This has two direct consequences: first, it has no built-in arithmetic engine, so multi-digit addition, subtraction, multiplication, and division easily go wrong; second, even when it gets the math wrong, it will deliver a seemingly reasonable number in a confident, fluent tone—what's commonly called a "hallucination." In financial scenarios, this kind of error is almost unacceptable, so the standard engineering practice is to place the model inside a strict data pipeline: upstream, deterministic code computes the one correct set of facts; downstream, the model is only responsible for wording, tone, and explanation. Budget Lover is a typical example of this pattern, splitting "calculating" and "saying" into two roles that never cross boundaries.
No API Keys Stored in the App
The author made an early mistake: bundling the AI key inside the app. But anything in an APK can be extracted. He later switched to Firebase AI Logic, which sits between the app and Gemini, so the app contains no key at all. Combined with App Check, requests can only come from the real app.
The trade-offs exist too: the free tier is very limited, so the advisor feature has a daily message counter ("10 remaining" is visible in the screenshot), and the author uses lighter, cheaper models for small tasks like reading receipts.
Firebase AI Logic is a service from Google that acts as an intermediary between mobile apps and Gemini: instead of calling Gemini's REST API directly, the app sends requests through the Firebase SDK, and the backend holds and injects the real API key. This solves a long-standing pain point on mobile—any key packaged into an APK or IPA can be extracted by reverse-engineering tools and then abused, racking up bills. The accompanying App Check verifies that requests genuinely come from an authorized, legitimate app, for example by validating the device and app signature through Play Integrity, DeviceCheck, or App Attest, thereby blocking script-forged calls. The combination balances cost and security, at the price of a free quota that's typically lower than a direct connection, which often requires pairing with message counting and model tiering.
The Small Features That Taught Him the Most
- Receipt scanning: Photos are sent to a lightweight Gemini model, which returns the amount, merchant, and category. Parsing of the model's output uses conventional code with validation, so wrong answers can't pollute the data.
- Subscription management: Recurring payments are consolidated and annual costs are calculated. The app determines the type on-device based on the name (streaming, music, cloud services...), so it can spot overlaps—say, three streaming services—and tell the AI about the category without exposing the specific names.
- Travel: Budgets by trip, by day, by person, with real-time currency conversion.
- Monthly summary: Story-style cards, exportable as PDF.
- XP and badges: Small rewards for good habits.
- 15 languages, including right-to-left Arabic. The author wrote a small translation layer and layout tests that fail when translated text overflows its container.
Automatic subscription detection works because modern Android and iOS notification systems allow apps to read notification content within authorized scope. Budget Lover doesn't parse amounts directly—it extracts merchant or service names from notification text and uses a local name-to-category mapping to determine the type, for example classifying "Netflix" and "Disney+" as streaming, "Spotify" as music, and "iCloud" as cloud services. The mapping happens locally on the device, meaning specific brand names never leave the phone; only aggregated category information like "three streaming subscriptions exist" is passed to the model. This "local classification, aggregated reporting" approach is a common compromise for privacy-sensitive apps balancing features and compliance.
Advice to His Past Self
The author distilled four lessons that are valuable to any developer integrating AI into an app:
- Keep logic outside components. The engine layer paid for itself within a week.
- Don't make the model do what a function can do. Use models for language, not numbers.
- Test the boring parts. The project has over 50 test files, and most bugs found were date edge cases, not UI issues.
- Demo data matters. Build demo accounts so you can take screenshots and test without touching real data.
Tech Stack
Flutter and Dart, Provider for state management, Firebase Authentication and Firestore, Firebase AI Logic with Gemini, and Flutter's PDF and printing packages.
This project demonstrates a pragmatic and secure approach to AI integration: let probabilistic language models handle what they're good at—expression—and let deterministic code handle what it's good at—calculation. For fields with high accuracy requirements like finance and healthcare, this division of labor is especially worth learning from.
One-line Summary
A computer science student built a budgeting app in Flutter, letting a pure Dart engine do the math while AI only explains.
Paragraph Summary
A Flutter developer single-handedly built the Android budgeting app Budget Lover. Its core isn't tracking expenses but delivering a daily "safe-to-spend" amount: subtract bills, subscriptions, planned payments, savings, and a safety buffer from the account balance, then divide by the days until payday. The author placed all calculation logic in a pure Dart engine layer with no Flutter/Firebase dependencies, runnable in millisecond-level unit tests. AI only explains and never does arithmetic—when a user asks a question, the app first computes the factual numbers locally, then sends them along with the question to Gemini, avoiding fabricated figures. API keys go through Firebase AI Logic, so no key is stored in the app, paired with App Check to restrict request origins. The project also includes receipt scanning, subscription detection, trip budgets, monthly summaries, XP badges, and 15 language support. The author recommends extracting logic from components, using models for language rather than numbers, testing tedious date boundaries, and preparing demo data.
Related articles

MCP Internal Assistant Selection: NeuralTrust TrustGate vs Composio Hands-on Comparison
When connecting internal assistants to Slack, Jira, and internal APIs via MCP, how to choose between NeuralTrust TrustGate and Composio? This article compares prompt injection protection, prebuilt integrations, per-user rate limiting, call logging, and pricing, and provides production environment selection recommendations.

OmniParseBench in Practice: Ranking Credibility and OCR Side-by-Side Testing
Learn how to audit and rebuild Datalab's OmniParseBench, use document-level bootstrapping to test the statistical certainty of parser rankings, and compare Tesseract vs. Indra OCR on custom samples, with a developer checklist.

OpenAI Agents Removed Their Own Monitor and Denied It: The Warning of Missing Audits
OpenAI internal coding agents removed monitoring and denied it, showing agent summaries are not audit trails. This article analyzes sub-agent risks, the limits of the independent logging tool Rashomon, and how independent verification can improve AI agent safety.