Skip to content
Finote

Finote

A React Native finance app with multiple wallets, weekly, monthly and yearly spending charts, and receipt photos stored on Cloudinary.

Type

Mobile App

Role

Mobile Developer

Built

Q4 2025

Updated

Q4 2026

Source

GitHub

Tech Stack

react-native
Expo
TypeScript
Firebase
Zod
cloudinary
reanimated
gifted-charts

TL;DR: Finote is a personal finance app built with React Native, Expo and TypeScript, using Firebase Firestore and Auth for data and login and Cloudinary for receipt images. Each wallet stores its own balance, income and expense totals, so the hard part is keeping those totals correct when a transaction is edited or moved to another wallet.

01

What it is

Finote is a personal finance app built with React Native and Expo, released as an Android APK. You create wallets like Salary, Freelance or Cash, log income and expenses against them with a category, notes and an optional receipt photo, and see spending trends in weekly, monthly and yearly charts.

Finote was also how I learned React Native. I wanted to understand the mobile-specific constraints the web never made me think about: gesture handling, 60fps animations on lower-end devices, and keeping data consistent across several documents.

02

Editing a transaction means undoing it first

Each wallet document in Firestore stores its own amount, totalIncome and totalExpenses, so reading a balance is one document read, with no summing over transactions. The catch: every write has to keep those three numbers correct.

A new transaction is the easy case: Finote checks the wallet, rejects an expense that would take the balance below zero, then adds the amount to totalIncome or totalExpenses. Editing is harder, because the old transaction already moved money. If the type, amount or wallet changed, revertAndUpdateWallets first reverses the old transaction on its original wallet, then applies the new values to the target wallet. It re-reads the target wallet in between, because when you edit within one wallet, that wallet was just updated. Turning an income into an expense on the same wallet, for example, has to undo the income before checking whether the balance can cover the expense.

Receipt photos go to Cloudinary as multipart FormData that points at the photo's file URI. My first version sent base64 strings, which bloated the payloads and blocked the JS thread while encoding.

03

What I'd change

These updates are separate network calls: the wallet writes, then the Cloudinary upload, then the transaction document. If the receipt upload fails, the wallet balance has already changed but no transaction is saved. I'd upload the receipt first and wrap the wallet and transaction writes in a single Firestore transaction (runTransaction), so they succeed or fail together.

04

FAQ

Q.01What is Finote?

Finote is a personal finance mobile app built with React Native and Expo. It lets you create multiple wallets such as Salary, Freelance or Cash, log transactions with a category, amount, notes and optional receipt photo, and view spending trends in weekly, monthly and yearly charts.

Q.02What tech stack does Finote use?

Finote is built with React Native, Expo and TypeScript, using Firebase Firestore for data, Firebase Auth for login, Cloudinary for receipt images, Zod for sign-up validation, Reanimated for animations and react-native-gifted-charts for spending charts.

Q.03How does Finote keep wallet balances correct when a transaction is edited?

When a Finote transaction's type, amount or wallet changes, Finote first reverses the old transaction's effect on its original wallet, then applies the new values to the target wallet. An expense that would push a wallet's balance below zero is rejected.

Q.04How does Finote upload receipt photos?

Finote uploads receipts to Cloudinary as multipart FormData that points at the photo's file URI, and Cloudinary optimizes them and serves them from a CDN. An earlier version sent base64 strings, which bloated payloads and blocked the main thread during encoding.

Q.05How does Finote build its spending charts?

Finote's statistics screen has Weekly, Monthly and Yearly tabs. Each one queries the user's transactions from Firestore for that range (the last 7 days, the last 12 months, or every year since the first transaction), sums income and expenses per bucket, and draws them as paired bars with react-native-gifted-charts.

Up Next

StarForge

An AI SaaS landing page template with parallax depth in the hero

Web App