DEV Community

vmodal_ai
vmodal_ai

Posted on • Originally published at example.com

Real-Time GPS Tracking with Flutter and WebSockets

Real-Time GPS Tracking with Flutter and WebSockets

Real-time location tracking is a core feature of delivery, fleet management, ride-sharing, logistics, and field-service applications. Polling an API every few seconds can waste battery and still introduce delays.

In this tutorial, we will build the architecture for real-time GPS tracking with Flutter and WebSockets. The Flutter app will collect location updates, send them through a WebSocket connection, and receive live updates from other clients.

The Architecture

A typical production architecture looks like this:

  1. Flutter obtains GPS coordinates.
  2. Flutter opens a WebSocket connection.
  3. The client sends location events to the backend.
  4. The backend validates and broadcasts updates.
  5. Other connected clients receive the new coordinates.
  6. The UI updates the marker without polling.

This approach is useful for delivery drivers, fleet dashboards, courier apps, and live tracking systems.

Prerequisites

You will need:

  • Flutter SDK
  • Dart
  • A WebSocket-capable backend
  • Location permissions
  • A physical device for realistic GPS testing

Add Dependencies

Add a location package and a WebSocket client to pubspec.yaml.

dependencies:
  flutter:
    sdk: flutter
  geolocator: ^latest
  web_socket_channel: ^latest
Enter fullscreen mode Exit fullscreen mode

Use the current compatible package versions when creating the project.

Configure Location Permissions

For Android, declare location permissions in AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
Enter fullscreen mode Exit fullscreen mode

Background tracking may require additional platform-specific configuration and user permission. Follow the requirements of your target Android and iOS versions.

Create a WebSocket Service

Keep networking outside your widgets.

import 'dart:convert';
import 'package:web_socket_channel/web_socket_channel.dart';

class LocationSocket {
  final WebSocketChannel channel;

  LocationSocket(String url)
      : channel = WebSocketChannel.connect(Uri.parse(url));

  void sendLocation({
    required double latitude,
    required double longitude,
  }) {
    channel.sink.add(jsonEncode({
      'type': 'location_update',
      'latitude': latitude,
      'longitude': longitude,
    }));
  }

  Stream<dynamic> get messages => channel.stream;

  Future<void> dispose() async {
    await channel.sink.close();
  }
}
Enter fullscreen mode Exit fullscreen mode

Listen to GPS Updates

Use Geolocator.getPositionStream() to receive location changes.

final positionStream = Geolocator.getPositionStream(
  locationSettings: const LocationSettings(
    accuracy: LocationAccuracy.high,
    distanceFilter: 10,
  ),
);

positionStream.listen((position) {
  socket.sendLocation(
    latitude: position.latitude,
    longitude: position.longitude,
  );
});
Enter fullscreen mode Exit fullscreen mode

The distanceFilter prevents the app from sending an update for every tiny movement.

Receive Live Locations

Other clients can listen for incoming WebSocket events:

socket.messages.listen((message) {
  final data = jsonDecode(message);

  if (data['type'] == 'location_update') {
    final latitude = data['latitude'];
    final longitude = data['longitude'];

    // Update your map marker here.
  }
});
Enter fullscreen mode Exit fullscreen mode

Connect this stream to your state-management layer instead of directly changing complex UI state.

Display the Location

Your map layer can consume a model such as:

class DriverLocation {
  final String driverId;
  final double latitude;
  final double longitude;

  const DriverLocation({
    required this.driverId,
    required this.latitude,
    required this.longitude,
  });
}
Enter fullscreen mode Exit fullscreen mode

When a new event arrives, update the corresponding marker.

Handle Connection Loss

Mobile networks change frequently. A production WebSocket client should handle:

  • Connection failures
  • Temporary network loss
  • Reconnection
  • Authentication expiration
  • Duplicate events

A simple reconnection strategy can use increasing delays:

Future<void> reconnect() async {
  for (var attempt = 1; attempt <= 5; attempt++) {
    try {
      // Create a new WebSocket connection.
      return;
    } catch (_) {
      await Future.delayed(
        Duration(seconds: attempt * 2),
      );
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

In production, also add jitter and avoid reconnecting continuously when the device is offline.

Secure the Connection

Always use wss:// in production.

wss://api.example.com/location
Enter fullscreen mode Exit fullscreen mode

Authenticate the WebSocket connection with a short-lived token. Never hard-code backend secrets in the Flutter application.

Optimize Battery Usage

Real-time GPS can consume significant battery power.

Consider:

  • Increasing the distance filter.
  • Reducing update frequency when the device is stationary.
  • Using appropriate location accuracy.
  • Stopping tracking when a delivery or trip ends.
  • Moving processing away from the main UI thread.

Production Architecture

For a larger application, separate responsibilities:

Flutter UI
   ↓
State Management
   ↓
Location Repository
   ↓
GPS Service + WebSocket Service
   ↓
Backend
   ↓
Database / Message Broker
Enter fullscreen mode Exit fullscreen mode

This makes the application easier to test and maintain.

Conclusion

WebSockets and Flutter provide a strong foundation for real-time location tracking. By combining a GPS stream with a persistent WebSocket connection, you can deliver location updates with much less overhead than frequent HTTP polling.

For production systems, focus on authentication, reconnection, battery consumption, background-location rules, and server-side validation. These details are just as important as drawing the location marker on the map.

Stay tuned for more advanced Flutter development tutorials!

Useful Links

SDK Flutter: https://github.com/v-modal/vmodal_sdk_flutter

SDK Android: https://github.com/v-modal/vmodal_sdk_android

Discord: https://discord.gg/K72z28KUx

Top comments (0)