Build a budgeting app with a Firestore transactions collection tracking income and expenses by category, and a budgets collection setting monthly spending limits per category. Display a dashboard with a balance summary, an expense breakdown PieChart using fl_chart as a Custom Widget, and budget progress bars showing spent versus limit. A Cloud Function triggers budget alerts when category spending exceeds the monthly threshold.
Personal finance tracker with category budgets and visual charts
A budgeting app helps users understand where their money goes. This tutorial builds one in FlutterFlow: users log income and expense transactions categorized by type, set monthly budgets per category, and view their financial health on a dashboard with a PieChart for expense breakdown and progress bars for budget tracking. A Cloud Function monitors spending and creates alert notifications when a category exceeds its budget. The result is a functional personal finance tracker built with visual tools.
Prerequisites
- A FlutterFlow project with Firebase/Firestore connected
- Firebase Authentication enabled with user sign-in working
- Basic familiarity with Custom Widgets and Action Flows
- An Option Set for expense categories (Food, Transport, Entertainment, Housing, etc.)
Step-by-step guide
Create the Firestore data model for transactions and budgets
Create the Firestore data model for transactions and budgets
In Firestore, create a transactions collection with fields: userId (String), amount (Double), type (String: 'income' or 'expense'), category (String from your Option Set: Food, Transport, Entertainment, Housing, Utilities, Shopping, Health, Other), date (Timestamp), and note (String, optional). Create a budgets collection with fields: userId (String), category (String), monthlyLimit (Double), currentSpent (Double, default 0), and month (String, format: '2026-03' for March 2026). Set Firestore rules so users can only read and write their own transactions and budgets (where userId == request.auth.uid). The month field on budgets allows querying the budget for the current month specifically.
Expected result: Firestore has transactions and budgets collections with proper fields and user-scoped security rules.
Build the Add Transaction form with category selection
Build the Add Transaction form with category selection
Create an AddTransactionPage or BottomSheet with the following inputs: a ToggleButtons widget with two options (Income and Expense) bound to Page State transactionType. An amount TextField with number keyboard and currency prefix. A category DropDown populated from your Option Set (only shown when type is Expense, hidden for Income via Conditional Visibility). A DateTimePicker defaulting to today. An optional note TextField. The Save button's On Tap Action Flow: validate that amount is greater than 0, then Create Document in transactions with all fields plus userId set to current user's UID. After creation, if type is 'expense', query the budgets collection for this user + category + current month. If a budget doc exists, Update Document with FieldValue.increment(amount) on the currentSpent field. Show a SnackBar confirming the transaction and navigate back to the dashboard.
Expected result: Users can log income and expense transactions with category, amount, date, and optional notes. Expense transactions update the corresponding budget's currentSpent.
Build the dashboard with balance summary and expense PieChart
Build the dashboard with balance summary and expense PieChart
Create a DashboardPage as the main screen. At the top, add three summary cards in a Row: Total Balance (income minus expenses for the current month), Total Income (green), and Total Expenses (red). Bind these to Backend Queries on transactions for the current month with appropriate filters. Below, add a Custom Widget using the fl_chart package to render a PieChart of expense breakdown by category. The widget accepts a List of category-amount pairs as a Component Parameter. Create a Custom Function that groups the current month's expense transactions by category and sums the amounts. Pass the result to the PieChart widget. Each slice should use a distinct color per category and show the percentage label. Below the chart, add a legend Row mapping colors to category names.
1// Custom Widget: ExpensePieChart2import 'package:fl_chart/fl_chart.dart';34class ExpensePieChart extends StatelessWidget {5 final List<CategoryAmount> data;6 const ExpensePieChart({required this.data});78 @override9 Widget build(BuildContext context) {10 final total = data.fold(0.0, (sum, item) => sum + item.amount);11 return PieChart(12 PieChartData(13 sections: data.map((item) {14 final pct = total > 0 ? (item.amount / total * 100) : 0;15 return PieChartSectionData(16 value: item.amount,17 title: '${pct.toStringAsFixed(0)}%',18 color: item.color,19 radius: 60,20 titleStyle: const TextStyle(fontSize: 12, color: Colors.white),21 );22 }).toList(),23 sectionsSpace: 2,24 centerSpaceRadius: 40,25 ),26 );27 }28}Expected result: The dashboard shows a balance summary and a PieChart breaking down expenses by category with color-coded slices and percentages.
Display budget progress bars per category
Display budget progress bars per category
Below the PieChart, add a section titled 'Budget Tracking'. Query the budgets collection where userId equals current user and month equals the current month string. Display results in a ListView. Each item is a Row containing: the category name Text, a LinearPercentIndicator with percent set to currentSpent / monthlyLimit (capped at 1.0 to avoid overflow), and a Text showing '$currentSpent / $monthlyLimit'. Set the progress bar color conditionally: green when under 75%, amber when 75-99%, red when at or over 100%. Add a Set Budget button that opens a BottomSheet with a category DropDown and monthlyLimit TextField. On save, create or update the budget doc for the selected category and current month.
Expected result: Each category budget displays a color-coded progress bar showing how much has been spent relative to the monthly limit.
Add monthly spending trend LineChart
Add monthly spending trend LineChart
Add a section below the budgets showing a 6-month spending trend. Create a Custom Widget using fl_chart's LineChart. Query transactions for the past 6 months grouped by month. Create a Custom Function that takes a list of transactions and returns monthly totals as a list of month-amount pairs. The LineChart shows months on the X axis and total spending on the Y axis. Use two lines: one for income (green) and one for expenses (red). Add touch interaction so tapping a data point shows a tooltip with the exact amount. This gives users a visual trend of their financial health over time.
Expected result: A LineChart shows the income and expense trends over the last 6 months with interactive tooltips.
Set up budget alert notifications via Cloud Function
Set up budget alert notifications via Cloud Function
Create a Cloud Function triggered onWrite to the budgets collection. When currentSpent is updated, check if currentSpent >= monthlyLimit. If so, create a notification document in users/{userId}/notifications with title 'Budget Alert', body 'You have exceeded your {category} budget of ${monthlyLimit} this month', and type 'budget_alert'. Also check at 80%: if currentSpent >= monthlyLimit * 0.8 AND a notification for 80% has not been sent yet (check a flag field notified80 on the budget doc), send a warning notification and set notified80 to true. Reset notified80 at the start of each month via a scheduled function that also resets currentSpent to 0 for all budgets.
Expected result: Users receive in-app notifications when they hit 80% and 100% of any category budget. Budgets reset monthly.
Complete working example
1Firestore Data Model:2├── transactions/{txnId}3│ ├── userId: String4│ ├── amount: Double (45.50)5│ ├── type: String ("income" | "expense")6│ ├── category: String ("Food" | "Transport" | ...)7│ ├── date: Timestamp8│ └── note: String (optional)9└── budgets/{budgetId}10 ├── userId: String11 ├── category: String ("Food")12 ├── monthlyLimit: Double (500.00)13 ├── currentSpent: Double (342.75)14 ├── month: String ("2026-03")15 └── notified80: Boolean (false)1617Dashboard Page:18├── Row (summary cards)19│ ├── Card (Balance: income - expenses, theme primary)20│ ├── Card (Income: green)21│ └── Card (Expenses: red)22├── Custom Widget: ExpensePieChart (fl_chart)23│ ├── Slices by category with percentages24│ └── Legend Row (color + category name)25├── Section: Budget Tracking26│ └── ListView (budgets for current month)27│ └── Row28│ ├── Text (category)29│ ├── LinearPercentIndicator (spent/limit, color: green/amber/red)30│ └── Text ("$342 / $500")31├── Section: Spending Trends32│ └── Custom Widget: LineChart (6-month income vs expense)33└── FAB → AddTransactionPage3435AddTransactionPage:36├── ToggleButtons (Income | Expense)37├── TextField (amount, number keyboard)38├── DropDown (category) [Cond. Vis: type == expense]39├── DateTimePicker (date)40├── TextField (note, optional)41└── Button (Save)42 └── On Tap → Create transaction → Update budget currentSpentCommon mistakes
Why it's a problem: Storing monthly totals only on the budget doc without recalculating from actual transactions
How to avoid: Recalculate currentSpent from actual transactions via a Cloud Function triggered on every transaction write. Query all expense transactions for the user, category, and month, sum them, and write the total to the budget doc.
Why it's a problem: Using a Timestamp for the month field on budget documents
How to avoid: Use a 'YYYY-MM' String format for the month field. This allows exact equality matching: where month == '2026-03'. It is simpler and faster than Timestamp range queries.
Why it's a problem: Not capping the LinearPercentIndicator percent value at 1.0
How to avoid: Use a Custom Function that returns min(currentSpent / monthlyLimit, 1.0). The progress bar fills to 100% and the color turns red, clearly indicating the budget is exceeded.
Best practices
- Use an Option Set for expense categories to maintain consistency across forms, charts, and filters
- Store the month as a 'YYYY-MM' string on budget docs for simple equality queries
- Recalculate budget totals from actual transactions to prevent drift from edits and deletions
- Cap LinearPercentIndicator at 1.0 and use red color to indicate budget exceeded
- Reset budgets monthly via a scheduled Cloud Function rather than relying on client-side logic
- Use fl_chart Custom Widgets for PieChart and LineChart since FlutterFlow has no built-in chart widgets
- Add budget alert notifications at 80% and 100% thresholds to help users course-correct spending
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
Design a Firestore data model for a personal budgeting app with transactions (income and expenses by category) and monthly budgets per category with a currentSpent field. Include a Cloud Function that checks if spending exceeds the budget limit and sends a notification.
Create a financial dashboard page with three summary cards at the top showing balance, total income, and total expenses. Below, add a PieChart breaking down expenses by category and a list of budget progress bars showing spent versus limit for each category.
Frequently asked questions
How do I create the expense PieChart without custom code?
FlutterFlow does not include a built-in chart widget. You must create a Custom Widget using the fl_chart pub package. The widget accepts category-amount data as a parameter and renders a PieChart with colored slices. This requires the Custom Widget feature available on all plans.
How do I reset budget spending at the start of each month?
Create a scheduled Cloud Function that runs on the 1st of each month. It queries all budget documents, creates new ones for the new month with currentSpent set to 0, and optionally archives the previous month's budgets for history. Reset the notified80 flag as well.
Can I add recurring transactions like rent or subscriptions?
Yes. Create a recurring_transactions collection with fields for amount, category, frequency (monthly, weekly), and nextDate. A scheduled Cloud Function checks daily for recurring transactions where nextDate equals today, creates the actual transaction, updates the budget, and advances nextDate to the next occurrence.
How do I handle multiple currencies?
Add a currency field to transactions and store amounts in their original currency. For dashboard totals, use a Custom Function that converts all amounts to the user's base currency using exchange rates from a third-party API (ExchangeRate-API or similar) fetched via an API Call.
Should I calculate totals in queries or Custom Functions?
For current month totals, query transactions with date range filters and sum in a Custom Function. Firestore does not support server-side aggregation like SUM(). For frequently accessed totals, denormalize monthly sums on a user_monthly_summary document updated by Cloud Functions.
Can RapidDev help build a full financial management platform?
Yes. A production finance app needs bank account integration (Plaid), recurring transaction automation, investment tracking, tax category mapping, PDF report generation, and data encryption at rest. RapidDev can build the complete system with secure Cloud Functions and third-party integrations.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation