Skip to main content
RapidDev - Software Development Agency
flutterflow-tutorials

How to Implement a Real-Time Stock Market Tracker in FlutterFlow

Build a stock tracker with a Firestore-backed watchlist, live price display, and historical chart. A scheduled Cloud Function fetches stock quotes from Alpha Vantage every 15 minutes and writes to a stock_quotes collection. The FlutterFlow app reads from Firestore with real-time listeners so prices update automatically. A Custom Widget using fl_chart renders interactive price history with selectable time ranges.

What you'll learn

  • How to fetch stock data via Cloud Functions and cache it in Firestore
  • How to build a user watchlist with real-time price updates
  • How to render interactive stock price charts with fl_chart
  • How to add symbol search and related news to the tracker
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner9 min read25-30 minFlutterFlow Pro+ (Custom Code required for chart widget)March 2026RapidDev Engineering Team
TL;DR

Build a stock tracker with a Firestore-backed watchlist, live price display, and historical chart. A scheduled Cloud Function fetches stock quotes from Alpha Vantage every 15 minutes and writes to a stock_quotes collection. The FlutterFlow app reads from Firestore with real-time listeners so prices update automatically. A Custom Widget using fl_chart renders interactive price history with selectable time ranges.

Building a Real-Time Stock Market Tracker in FlutterFlow

Stock tracking apps need live data, interactive charts, and personalized watchlists. This tutorial shows you how to fetch market data through a scheduled Cloud Function, store it in Firestore, display a watchlist with green/red price changes, render historical price charts, and integrate a news feed — all within FlutterFlow's visual builder.

Prerequisites

  • A FlutterFlow project on the Pro plan or higher
  • Firebase project with Firestore and Cloud Functions enabled
  • An Alpha Vantage or Polygon.io API key (free tier available)
  • Basic familiarity with Cloud Functions and Backend Queries in FlutterFlow

Step-by-step guide

1

Set up the Cloud Function to fetch and cache stock quotes

Create a scheduled Cloud Function that runs every 15 minutes (matching free API tier limits). The function reads a list of tracked symbols from a Firestore `tracked_symbols` document, calls the Alpha Vantage Global Quote endpoint for each symbol, and writes the response data to `stock_quotes/{symbol}` documents with fields: symbol (String), price (double), change (double), changePercent (String), volume (int), high (double), low (double), and lastUpdated (Timestamp). Store your Alpha Vantage API key in Cloud Functions environment config, never in client code.

fetchStockQuotes.js
1// Cloud Function: fetchStockQuotes
2// Scheduled: every 15 minutes
3const functions = require('firebase-functions');
4const admin = require('firebase-admin');
5const fetch = require('node-fetch');
6admin.initializeApp();
7
8exports.fetchStockQuotes = functions.pubsub
9 .schedule('every 15 minutes')
10 .onRun(async () => {
11 const db = admin.firestore();
12 const apiKey = functions.config().alphavantage.key;
13 const doc = await db.doc('config/tracked_symbols').get();
14 const symbols = doc.data().symbols || [];
15
16 for (const symbol of symbols) {
17 const url = `https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${symbol}&apikey=${apiKey}`;
18 const res = await fetch(url);
19 const data = await res.json();
20 const q = data['Global Quote'];
21 if (!q) continue;
22
23 await db.doc(`stock_quotes/${symbol}`).set({
24 symbol,
25 price: parseFloat(q['05. price']),
26 change: parseFloat(q['09. change']),
27 changePercent: q['10. change percent'],
28 volume: parseInt(q['06. volume']),
29 high: parseFloat(q['03. high']),
30 low: parseFloat(q['04. low']),
31 lastUpdated: admin.firestore.FieldValue
32 .serverTimestamp(),
33 });
34 }
35 });

Expected result: Stock quotes update in Firestore every 15 minutes automatically. The client never calls the stock API directly.

2

Build the watchlist page with real-time prices

Create a Watchlist page. Store each user's watched symbols in a `users/{uid}/watchlist` subcollection, each document containing a symbol field. Add a Backend Query on this subcollection to get the user's symbols. For each symbol, run a second Backend Query on `stock_quotes/{symbol}` with Single Time Query set to OFF for real-time updates. Display each stock in a ListView with a Container showing: symbol (bold Text), price (Text), and change with changePercent in green (positive) or red (negative) using Conditional Styling. Add a sparkline by storing the last 20 price points in an array field on the stock_quotes document.

Expected result: Users see their watched stocks with live prices that update every 15 minutes. Positive changes appear green and negative changes appear red.

3

Add stock symbol search and watchlist management

At the top of the Watchlist page, add a TextField with a search icon for entering stock symbols. On submit, call an API endpoint (Alpha Vantage Symbol Search) via a Cloud Function that returns matching symbols with company names. Display results in a ListView below the search field. Each result shows the symbol, company name, and an Add to Watchlist IconButton. The Add action creates a document in `users/{uid}/watchlist` with the symbol and also adds the symbol to the `config/tracked_symbols` array (using FieldValue.arrayUnion) so the scheduled function starts fetching it. Add a swipe-to-dismiss gesture on watchlist items that deletes the symbol from the user's watchlist subcollection.

Expected result: Users can search for stock symbols, add them to their watchlist, and remove them by swiping.

4

Create the stock detail page with a price history chart

When a user taps a stock in the watchlist, navigate to a StockDetail page passing the symbol as a parameter. Fetch historical data by calling the Alpha Vantage Daily endpoint via a Cloud Function and store results in `stock_history/{symbol}` with a prices array of {date, close} objects. Create a Custom Widget named StockChart using fl_chart's LineChart. The widget takes a list of price points and renders them as a curved line with gradient fill beneath. Add ChoiceChips above the chart for time range selection: 1D, 1W, 1M, 3M, 1Y. Each selection filters the price data array to the appropriate date range and rebuilds the chart.

stock_chart.dart
1// Custom Widget: StockChart (simplified)
2import 'package:flutter/material.dart';
3import 'package:fl_chart/fl_chart.dart';
4
5class StockChart extends StatelessWidget {
6 final double width;
7 final double height;
8 final List<double> prices;
9
10 const StockChart({
11 Key? key,
12 required this.width,
13 required this.height,
14 required this.prices,
15 }) : super(key: key);
16
17 @override
18 Widget build(BuildContext context) {
19 final spots = prices.asMap().entries.map(
20 (e) => FlSpot(e.key.toDouble(), e.value),
21 ).toList();
22
23 final isPositive = prices.last >= prices.first;
24 final color = isPositive ? Colors.green : Colors.red;
25
26 return SizedBox(
27 width: width,
28 height: height,
29 child: LineChart(LineChartData(
30 gridData: const FlGridData(show: false),
31 titlesData: const FlTitlesData(show: false),
32 borderData: FlBorderData(show: false),
33 lineBarsData: [
34 LineChartBarData(
35 spots: spots,
36 isCurved: true,
37 color: color,
38 barWidth: 2,
39 dotData: const FlDotData(show: false),
40 belowBarData: BarAreaData(
41 show: true,
42 color: color.withOpacity(0.1),
43 ),
44 ),
45 ],
46 )),
47 );
48 }
49}

Expected result: The stock detail page shows an interactive price chart with time range selection. The line color is green for positive trends and red for negative.

5

Add a news feed for the selected stock

Below the chart on the StockDetail page, add a News section. Create a Cloud Function that fetches news articles from a news API (like NewsAPI.org) filtered by the stock's company name. Cache results in `stock_news/{symbol}` with an articles array containing title, source, publishedAt, url, and imageUrl fields. Update the cache hourly via a scheduled function. In FlutterFlow, add a Backend Query on the stock_news document and bind results to a ListView. Each news item shows a Container with the article image, title, source name, and publication time. Tapping an item calls Launch URL to open the full article in the browser.

Expected result: The stock detail page displays relevant news articles below the price chart, and users can tap to read full articles.

Complete working example

StockChart Custom Widget + Cloud Function
1// Custom Widget: StockChart
2// Pubspec: fl_chart: ^0.66.0
3
4import 'package:flutter/material.dart';
5import 'package:fl_chart/fl_chart.dart';
6
7class StockChart extends StatelessWidget {
8 final double width;
9 final double height;
10 final List<double> prices;
11 final String timeRange;
12
13 const StockChart({
14 Key? key,
15 required this.width,
16 required this.height,
17 required this.prices,
18 this.timeRange = '1M',
19 }) : super(key: key);
20
21 @override
22 Widget build(BuildContext context) {
23 if (prices.isEmpty) {
24 return SizedBox(
25 width: width,
26 height: height,
27 child: const Center(child: Text('No data')),
28 );
29 }
30
31 final spots = prices.asMap().entries
32 .map((e) => FlSpot(e.key.toDouble(), e.value))
33 .toList();
34
35 final isPositive = prices.last >= prices.first;
36 final lineColor = isPositive ? Colors.green : Colors.red;
37
38 return SizedBox(
39 width: width,
40 height: height,
41 child: LineChart(
42 LineChartData(
43 gridData: FlGridData(
44 show: true,
45 drawVerticalLine: false,
46 horizontalInterval: _calcInterval(),
47 getDrawingHorizontalLine: (v) => FlLine(
48 color: Colors.grey.withOpacity(0.2),
49 strokeWidth: 1,
50 ),
51 ),
52 titlesData: const FlTitlesData(show: false),
53 borderData: FlBorderData(show: false),
54 lineTouchData: LineTouchData(
55 touchTooltipData: LineTouchTooltipData(
56 getTooltipItems: (spots) => spots.map((s) =>
57 LineTooltipItem(
58 '\$${s.y.toStringAsFixed(2)}',
59 const TextStyle(
60 color: Colors.white,
61 fontWeight: FontWeight.bold,
62 ),
63 ),
64 ).toList(),
65 ),
66 ),
67 lineBarsData: [
68 LineChartBarData(
69 spots: spots,
70 isCurved: true,
71 color: lineColor,
72 barWidth: 2,
73 dotData: const FlDotData(show: false),
74 belowBarData: BarAreaData(
75 show: true,
76 color: lineColor.withOpacity(0.1),
77 ),
78 ),
79 ],
80 ),
81 ),
82 );
83 }
84
85 double _calcInterval() {
86 if (prices.isEmpty) return 1;
87 final max = prices.reduce((a, b) => a > b ? a : b);
88 final min = prices.reduce((a, b) => a < b ? a : b);
89 return ((max - min) / 5).clamp(0.01, double.infinity);
90 }
91}

Common mistakes when implementing a Real-Time Stock Market Tracker in FlutterFlow

Why it's a problem: Calling the stock API directly from the FlutterFlow client on every page load

How to avoid: Fetch data via a scheduled Cloud Function every 15 minutes and store results in Firestore. The client reads from Firestore with real-time listeners instead of calling the API directly.

Why it's a problem: Displaying stale prices without showing when the data was last updated

How to avoid: Always display the lastUpdated timestamp on the watchlist and detail pages. Add a 'Data delayed 15 min' disclaimer and show the time since last update.

Why it's a problem: Not handling API failures gracefully in the Cloud Function

How to avoid: Check for valid data in the API response before writing to Firestore. If the response is an error, skip the update and log the failure. Existing data remains unchanged.

Best practices

  • Use Conditional Styling to color price changes green for positive and red for negative — this is the universal visual language for stock data
  • Cache historical price data in Firestore to avoid repeated API calls for the same date range
  • Add a 'Data delayed 15 minutes' disclaimer since free API tiers do not provide real-time quotes
  • Store the user's watchlist symbols in a subcollection for efficient per-user queries
  • Limit the tracked_symbols config to under 25 symbols on the free API tier to stay within rate limits
  • Use fl_chart's touch tooltip to show exact price values when users tap on the chart line
  • Add pull-to-refresh that triggers a manual Cloud Function call for on-demand price updates

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I'm building a stock market tracker in FlutterFlow. I need a Cloud Function that fetches stock quotes from Alpha Vantage every 15 minutes and stores them in Firestore. Then I need a watchlist page with real-time price updates and a detail page with an fl_chart line chart for price history. Show me the schema and code.

FlutterFlow Prompt

Create a stock watchlist page showing stock symbols with their current price, daily change in green or red, and a small sparkline chart. Add a search bar at the top to find and add stocks. Tapping a stock should navigate to a detail page with a larger price chart and time range selector.

Frequently asked questions

Can I use a different stock API instead of Alpha Vantage?

Yes. Polygon.io, Finnhub, and Yahoo Finance API all work. Update the Cloud Function endpoint URL and response parsing to match the new API's format. The Firestore schema and FlutterFlow UI remain the same.

How do I show real-time stock prices instead of 15-minute delayed data?

Real-time market data requires a paid API subscription (e.g., Polygon.io WebSocket feed). Connect via a Cloud Function that maintains a WebSocket connection and writes to Firestore on each price update.

Can I add price alerts that notify users when a stock hits a target price?

Yes. Store alert thresholds in a user_alerts subcollection. In the scheduled Cloud Function, after fetching quotes, check if any price crosses a user's threshold and send an FCM push notification.

Does the chart support pinch-to-zoom for detailed price analysis?

fl_chart does not natively support pinch-to-zoom. You can wrap the chart in an InteractiveViewer widget to enable zoom and pan, or use a different charting package like syncfusion_flutter_charts.

How many stocks can I track on the free Alpha Vantage plan?

The free tier allows 5 API calls per minute and 500 per day. With the Cloud Function running every 15 minutes (96 runs/day), you can track about 5 symbols reliably. Upgrade to the premium tier for more symbols.

Can RapidDev help build a full investment portfolio tracker?

Yes. RapidDev can implement portfolio tracking with holdings, cost basis, gain/loss calculations, dividend tracking, sector allocation charts, and real-time data feeds.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.