Update Stream based ChangeNotifier

Viewed 344

I have a statefull widget that uses a stream provider to show some markers which get updated in real time. I wan to be able to change the stream based on the center of the map, when a user moves the map camera. I have set up the following MultiProviders:

MultiProvider(providers: [
        ChangeNotifierProvider(create: (context) => TabManager()),
            FutureProvider<Position?>(
                create: (_) => _geoLocatorSrv.getCurrentPosition(),
                initialData: null),
            ChangeNotifierProxyProvider<Position, GeoLocatorService>(
                create: (_) => _geoLocatorSrv,
                update: (ctx, position, geoLocator) {
                  return GeoLocatorService.fromCameraPosition(
                      CameraPosition(
                          target: LatLng(
                              position.latitude, position.longitude)));
                }),
            StreamProvider<List<ParkingSpot>>(
              create: (_) => _db.getParkingSpots(
                  "parking-events/chirpstack/applications/1/devices", null),
              initialData: const [],
            ),
            ProxyProvider<GeoLocatorService, Stream<List<ParkingSpot>>>(
              update: (_, geoLocatorService, parkingSpots) {
                log("ProxyProvider GeolocationService updated");
                return _db.getParkingSpots("collections");
              }
            )

      ]

My goal is to

  1. Get current location
  2. Upon location received create a GeoLocatorService (change notifier) with the value of the geo locator future
  3. Create a stream provider which "streams" collection data
  4. ProxyProvider which updates the stream based on changes in the GeoLocatorService changes in the camera position.

on my map statefull widget i have the following:

@override
Widget build(BuildContext context) {
  var parkingSpots = Provider.of<List<ParkingSpot>>(context); # get the streamprovider with the items from the db
  var currentPosition = Provider.of<Position?>(context); Get the current position
  var geoLocatorNotifier = Provider.of<GeoLocatorService>(context); # get the notifier 


  CameraPosition? newCamPosition; 
   return Scaffold(
    body: (currentPosition != null ) ? GoogleMap(
        initialCameraPosition: _initialCameraPosition,
        onMapCreated: (ctrl) {
          _controller.complete(ctrl);
        },
        onCameraIdle: () {
            
          if (newCamPosition != null){
            geoLocatorNotifier.setCameraPosition(newCamPosition); //this is never called
          }
        },
        onCameraMove: (position) {
          setState(() {
            newCamPosition = position;
          });

        },
        myLocationButtonEnabled: false,
        zoomControlsEnabled: false,
      ) : const Center(child: CircularProgressIndicator()),
      floatingActionButton: FloatingActionButton(
        backgroundColor: Theme.of(context).primaryColor,
        foregroundColor: Colors.white,
        onPressed: () async {
          GoogleMapController ctrl = await _controller.future;
          ctrl.animateCamera(
              CameraUpdate.newCameraPosition(_initialCameraPosition));
        },
        child: const Icon(Icons.center_focus_strong)),
  );
}

setCameraPosition in the GeoLocatorService is the following:

setCameraPosition(CameraPosition? position) {
    cameraPosition = position;
    notifyListeners();
}

But the stream never gets updated. Code in update callback in ProxyProvider<GeoLocatorService, Stream<List<ParkingSport>>>(). How can I have a StreamProvider update it's value based on a value of a ChangeNotifer?

0 Answers
Related