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

How to Set Up a Food Delivery Tracking System in FlutterFlow

Build a delivery tracking system with an orders collection tracking status through placed, preparing, picked_up, delivering, and delivered stages, plus a drivers collection storing real-time lat/lng coordinates. The customer page shows a status stepper and a live Google Map with restaurant and driver markers. The driver updates location every 10 seconds via geolocator, and status buttons advance the order through each stage. Real-time Firestore queries keep everything updated.

What you'll learn

  • How to model delivery orders with multi-stage status tracking
  • How to display a live map with moving driver markers and route polylines
  • How to update driver location in real time using the geolocator package
  • How to build driver-side order management with status progression buttons
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner8 min read30-35 minFlutterFlow Pro+ (Custom Widget and Custom Actions required)March 2026RapidDev Engineering Team
TL;DR

Build a delivery tracking system with an orders collection tracking status through placed, preparing, picked_up, delivering, and delivered stages, plus a drivers collection storing real-time lat/lng coordinates. The customer page shows a status stepper and a live Google Map with restaurant and driver markers. The driver updates location every 10 seconds via geolocator, and status buttons advance the order through each stage. Real-time Firestore queries keep everything updated.

Building a Real-Time Delivery Tracking System in FlutterFlow

Food delivery tracking gives customers visibility into their order's journey from restaurant to doorstep. This tutorial builds both the customer and driver experiences: a status stepper showing order progression, a live map with driver position and route, automatic location updates via geolocator, and driver-side controls for advancing order status. It applies to food delivery, courier services, or any logistics app.

Prerequisites

  • A FlutterFlow project on the Pro plan with Custom Widgets enabled
  • Google Maps API key with Maps SDK and Directions API enabled
  • Firebase project with Firestore and Authentication
  • The geolocator and google_maps_flutter packages
  • Location permissions configured in your app settings

Step-by-step guide

1

Create the orders and drivers Firestore schema

Create an orders collection with fields: userId (String), restaurantId (String), restaurantLat (Double), restaurantLng (Double), items (List of Maps with name, qty, price), total (Double), status (String: 'placed', 'preparing', 'picked_up', 'delivering', 'delivered'), driverId (String, nullable, assigned when driver accepts), estimatedDeliveryTime (Timestamp), deliveryAddress (String), deliveryLat (Double), deliveryLng (Double), and createdAt (Timestamp). Create a drivers collection with: userId (String), displayName (String), currentLat (Double), currentLng (Double), isAvailable (Boolean), and lastLocationUpdate (Timestamp).

Expected result: Firestore has orders and drivers collections. Orders track multi-stage status and delivery coordinates. Drivers have real-time location fields.

2

Build the customer order tracking page with status stepper

Create an OrderTracking page that receives an orderId as a Page Parameter. Add a Backend Query on the order document with Single Time Query OFF for real-time updates. At the top, display a vertical Stepper-style Column with 5 rows representing order stages: Placed (checkmark), Preparing (cooking icon), Picked Up (bag icon), Delivering (motorcycle icon), and Delivered (home icon). For each row, use a Container with a circle icon. Apply Conditional Styling: completed stages show a filled green circle, the current stage shows a pulsing blue circle, and future stages show a grey outline. Connect circles with vertical lines. Below the stepper, show the estimated delivery time and driver name when assigned.

Expected result: The order tracking page shows a real-time status stepper that progresses through delivery stages as the driver updates the status.

3

Add the live map with restaurant and driver markers

Below the status stepper, add a FlutterFlowGoogleMap or a Custom Widget using google_maps_flutter. Create three markers: a restaurant marker (at restaurantLat/Lng with a red pin), a delivery destination marker (at deliveryLat/Lng with a green pin), and a driver marker (at the driver's currentLat/currentLng from a real-time Backend Query on the driver document). Set Single Time Query OFF on the driver query so the driver marker moves as coordinates update. When status is 'delivering', show a polyline between the driver and destination. Use the Google Directions API to draw a route polyline between the two points.

Expected result: The map shows the restaurant, delivery destination, and driver markers. The driver marker moves in real time as the driver's position updates.

4

Build driver-side location sharing with geolocator

Create a Custom Action called updateDriverLocation using the geolocator package. The action gets the current position via Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high), then updates the driver's Firestore document with currentLat, currentLng, and lastLocationUpdate. On the driver's active delivery page, use a Timer action that fires this Custom Action every 10 seconds while the order status is 'picked_up' or 'delivering'. Stop the timer when the order reaches 'delivered'. Request location permissions on the driver's page load.

update_driver_location.dart
1// Custom Action: updateDriverLocation
2import 'package:geolocator/geolocator.dart';
3import 'package:cloud_firestore/cloud_firestore.dart';
4
5Future<void> updateDriverLocation(String driverDocId) async {
6 bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
7 if (!serviceEnabled) return;
8
9 LocationPermission permission = await Geolocator.checkPermission();
10 if (permission == LocationPermission.denied) {
11 permission = await Geolocator.requestPermission();
12 if (permission == LocationPermission.denied) return;
13 }
14
15 final position = await Geolocator.getCurrentPosition(
16 desiredAccuracy: LocationAccuracy.high,
17 );
18
19 await FirebaseFirestore.instance
20 .collection('drivers')
21 .doc(driverDocId)
22 .update({
23 'currentLat': position.latitude,
24 'currentLng': position.longitude,
25 'lastLocationUpdate': FieldValue.serverTimestamp(),
26 });
27}

Expected result: The driver's location updates in Firestore every 10 seconds during active delivery. The customer's map reflects these updates in real time.

5

Build driver-side order management with status buttons

Create a DriverOrderPage for the driver interface. Display the order details (items, customer address, total) at the top. Below, add contextual action buttons that change based on the current status. When status is 'placed' and the driver is assigned, show an 'Accept Order' button. When 'preparing', show 'Mark as Picked Up'. When 'picked_up', show 'Start Delivery' (changes to 'delivering' and starts location tracking). When 'delivering', show 'Mark as Delivered'. Each button updates the order status via an Update Document action. On 'delivering', also start the 10-second location timer. On 'delivered', stop the timer and set isAvailable to true on the driver document.

Expected result: Drivers see contextual action buttons that advance the order through each status stage. Location tracking starts automatically during delivery.

6

Add estimated delivery time and delivery confirmation

When the driver taps 'Start Delivery', calculate the estimated delivery time using the Google Directions API. Call the API with origin (driver's current position) and destination (delivery address), parse the duration from the response, add it to the current time, and update estimatedDeliveryTime on the order document. The customer's tracking page reads this field and shows a countdown: 'Arriving in ~X minutes'. When the driver taps 'Mark as Delivered', update the order status, stop location tracking, and trigger a push notification to the customer saying 'Your order has been delivered!'. Show a delivery confirmation screen to both driver and customer.

Expected result: Customers see an estimated delivery countdown that updates when delivery starts. Both parties receive confirmation when the order is delivered.

Complete working example

update_driver_location.dart
1// Custom Action: Driver Location Tracker
2// Add to Pubspec: geolocator: ^11.0.0
3import 'dart:async';
4import 'package:geolocator/geolocator.dart';
5import 'package:cloud_firestore/cloud_firestore.dart';
6
7class DriverLocationTracker {
8 Timer? _timer;
9 final String driverDocId;
10
11 DriverLocationTracker(this.driverDocId);
12
13 void startTracking({int intervalSeconds = 10}) {
14 _timer?.cancel();
15 _updateLocation(); // immediate first update
16 _timer = Timer.periodic(
17 Duration(seconds: intervalSeconds),
18 (_) => _updateLocation(),
19 );
20 }
21
22 void stopTracking() {
23 _timer?.cancel();
24 _timer = null;
25 }
26
27 Future<void> _updateLocation() async {
28 try {
29 bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
30 if (!serviceEnabled) return;
31
32 LocationPermission permission = await Geolocator.checkPermission();
33 if (permission == LocationPermission.denied) {
34 permission = await Geolocator.requestPermission();
35 if (permission == LocationPermission.denied) return;
36 }
37 if (permission == LocationPermission.deniedForever) return;
38
39 final position = await Geolocator.getCurrentPosition(
40 desiredAccuracy: LocationAccuracy.high,
41 );
42
43 await FirebaseFirestore.instance
44 .collection('drivers')
45 .doc(driverDocId)
46 .update({
47 'currentLat': position.latitude,
48 'currentLng': position.longitude,
49 'lastLocationUpdate': FieldValue.serverTimestamp(),
50 });
51 } catch (e) {
52 // Silently handle — next interval will retry
53 }
54 }
55
56 bool get isTracking => _timer?.isActive ?? false;
57}

Common mistakes

Why it's a problem: Updating driver location to Firestore every second

How to avoid: Update every 10-15 seconds, which provides smooth enough tracking at a fraction of the cost. Increase to 30 seconds for long-distance deliveries.

Why it's a problem: Not stopping location tracking after delivery is complete

How to avoid: Cancel the timer and stop location updates when the order status changes to 'delivered' or when the driver goes offline.

Why it's a problem: Showing the driver marker at 0,0 coordinates before any location update

How to avoid: Only show the driver marker when lastLocationUpdate is not null and currentLat/currentLng are non-zero. Hide the marker with Conditional Visibility during initialization.

Best practices

  • Update driver location every 10-15 seconds for an optimal balance between accuracy and cost
  • Use real-time Firestore queries (Single Time Query OFF) for both order status and driver position
  • Show the estimated delivery time as a countdown to set customer expectations
  • Add a Navigate to Maps button for drivers to get turn-by-turn directions in their native maps app
  • Send push notifications at key status changes: order accepted, picked up, and delivered
  • Set the driver's isAvailable flag to false when they accept an order and true when they complete delivery
  • Cache the Directions API route polyline to avoid repeated API calls as the driver position updates

Still stuck?

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

ChatGPT Prompt

I need to build a food delivery tracking system in FlutterFlow. Show me the Firestore schema for orders with multi-stage status tracking and drivers with real-time coordinates, the Custom Action for updating driver location using geolocator every 10 seconds, and the customer-facing map with restaurant, driver, and destination markers.

FlutterFlow Prompt

Create an order tracking page with a vertical status stepper showing order progress through 5 stages and a Google Map below it showing the restaurant, driver, and delivery destination markers. The driver marker should update in real time from Firestore.

Frequently asked questions

How do I handle driver assignment when multiple drivers are available?

Create a Cloud Function that queries available drivers sorted by distance from the restaurant (using lat/lng comparison), then assigns the closest available driver. Update the order's driverId and the driver's isAvailable field atomically.

Can I show the driver's location while the app is in the background?

Yes, but it requires background location permissions and the geolocator_platform_interface setup for background mode. Be aware this drains battery faster and requires additional permission justifications for app store review.

How do I calculate and display the delivery ETA accurately?

Call the Google Directions API with the driver's current position and delivery address. Parse the duration_in_traffic field for traffic-aware estimates. Update estimatedDeliveryTime on the order document each time the driver's position updates significantly.

Can I add delivery instructions from the customer?

Yes. Add a deliveryInstructions String field to the orders collection. Display it on the driver's order page below the delivery address. Allow customers to set it during checkout.

How do I handle orders where the driver cannot reach the customer?

Add a 'Cannot Deliver' button on the driver page that changes status to 'failed_delivery' and notifies the customer and restaurant. Include options for retry, refund, or rescheduling.

Can RapidDev build a full food delivery platform?

Yes. RapidDev can implement the complete system including restaurant management, menu builder, order routing, multi-driver dispatch, real-time tracking, payment processing, and analytics dashboards.

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.