Flutter Live Location Tracking using Supabase



To implement live location tracking with polylines from the start coordinates to destination coordinates, and to use Supabase for real-time updates, you can follow this approach.

Steps:

  1. Set Up Supabase:
    • Sign up on Supabase.
    • Create a project and a table to store location updates (with columns like latitude, longitude, timestamp, user_id).
    • Use Supabase’s real-time features to broadcast location changes.
  2. Add Supabase and Necessary Packages: In your pubspec.yaml, include the following dependencies:
    dependencies:
      flutter:
        sdk: flutter
      google_maps_flutter: ^2.1.7
      location: ^4.3.0
      supabase_flutter: ^1.0.0
      polyline_do: ^1.0.0
    
  3. Supabase Setup: Add Supabase's API Key and URL in your project.
  4. Flutter Code Implementation with Polylines and Real-time Updates:
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Supabase.initialize(
    url: 'your-supabase-url',
    anonKey: 'your-supabase-anon-key',
  );
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Live Location with Supabase',
      home: LiveLocationWithPolyline(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class LiveLocationWithPolyline extends StatefulWidget {
  @override
  _LiveLocationWithPolylineState createState() =>
      _LiveLocationWithPolylineState();
}

class _LiveLocationWithPolylineState extends State<LiveLocationWithPolyline> {
  late GoogleMapController _mapController;
  Location _location = Location();
  LatLng _initialPosition = LatLng(37.42796133580664, -122.085749655962);
  LatLng? _destination;
  Set<Polyline> _polylines = {};
  List<LatLng> polylineCoordinates = [];
  bool _liveUpdate = true;
  final SupabaseClient supabase = Supabase.instance.client;

  void _onMapCreated(GoogleMapController controller) {
    _mapController = controller;
    _location.onLocationChanged.listen((LocationData locationData) async {
      if (_liveUpdate) {
        LatLng currentPosition =
            LatLng(locationData.latitude!, locationData.longitude!);

        _mapController.animateCamera(
          CameraUpdate.newCameraPosition(
            CameraPosition(target: currentPosition, zoom: 16.0),
          ),
        );

        if (_destination != null) {
          polylineCoordinates.add(currentPosition);
          setState(() {
            _polylines.add(
              Polyline(
                polylineId: PolylineId('route'),
                points: polylineCoordinates,
                color: Colors.blue,
                width: 5,
              ),
            );
          });
        }

        // Update current location to Supabase
        await supabase.from('locations').insert({
          'latitude': locationData.latitude!,
          'longitude': locationData.longitude!,
          'timestamp': DateTime.now().toIso8601String(),
          'user_id': 'user_1', // Add your user identification logic
        });
      }
    });
  }

  void _trackSupabaseUpdates() {
    supabase
        .from('locations')
        .on(SupabaseEventTypes.insert, (payload) {
          final data = payload.newRecord;
          LatLng newLocation =
              LatLng(data['latitude'], data['longitude']);

          if (_destination == null) {
            _destination = newLocation;
            setState(() {
              polylineCoordinates.add(_initialPosition);
              polylineCoordinates.add(newLocation);
            });
          }
        })
        .subscribe();
  }

  @override
  void initState() {
    super.initState();
    _location.requestPermission().then((granted) {
      if (granted == PermissionStatus.granted) {
        _trackSupabaseUpdates();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Live Location with Supabase"),
        actions: [
          Switch(
            value: _liveUpdate,
            onChanged: (value) {
              setState(() {
                _liveUpdate = value;
              });
            },
            activeColor: Colors.green,
            inactiveThumbColor: Colors.red,
          ),
        ],
      ),
      body: _initialPosition == null
          ? Center(child: CircularProgressIndicator())
          : GoogleMap(
              initialCameraPosition: CameraPosition(
                target: _initialPosition,
                zoom: 16.0,
              ),
              onMapCreated: _onMapCreated,
              myLocationEnabled: true,
              myLocationButtonEnabled: true,
              mapType: MapType.normal,
              polylines: _polylines,
            ),
    );
  }
}


Key Features:

  1. Live Location Tracking with Polylines: The code listens for real-time location updates using the Location package and draws polylines on the map to show the path from the start to the destination.
  2. Supabase Realtime: Every time the location changes, it is stored in the Supabase database. Other clients can receive real-time updates via Supabase’s real-time subscriptions. In this case, the new destination is tracked from Supabase updates.
  3. Polyline Display: As the user's location updates, a polyline (blue line) is drawn on the map showing the route to the destination.

Notes:

  • Ensure that you have set up your Supabase instance with a locations table containing columns like latitude, longitude, timestamp, and user_id.
  • You can refine how real-time updates are handled to manage multiple users and optimize location updates for performance.

 

Previous Post Next Post

نموذج الاتصال