transistorsoft / flutter_background_geolocation_firebase

Firebase proxy for Flutter Background Geolocation SDK
MIT License
21 stars 7 forks source link

Throttle the Frequency of Location Updates to Firebase #9

Open fne00 opened 4 years ago

fne00 commented 4 years ago

Chris, My app needs frequent location updates to perform its functions, but I only need less frequent location updates to Firebase.

Would you consider adding a parameter such as:

I would continue to take location updates as quickly as they are available, but set this to parameter somewhere in the range 10 to 60 seconds.

Alternatively is there a way I can intercept updates to firebase myself to achieve this?

Peter

christocracy commented 4 years ago

There is no way to handle this currently. It would not be implemented in the Firebase adapter, it would should be implemented in flutter_background_geolocation.

christocracy commented 4 years ago

You could manually manage this via BackgroundGeolocation#setConfig with Config.maxRecordsToPersist, oscillating between setting that to 0 and -1 with your own logic.

fne00 commented 4 years ago

Chris, Thanks for the suggestion, but it's not working for me (as yet, anyway).

In my void _onLocation(bg.Location location) I have added:

   // handle throttling updates to Firebase
    if (liveFireStoreEnabled)  {

      DateTime now = DateTime.now();
      if(now.isAfter(lastUpdateToFirebase.add(Duration(seconds: liveFireStoreInterval ))))
      {
        bg.BackgroundGeolocation.setConfig(bg.Config(maxRecordsToPersist: -1)); // no limit - store point(s) to SQL and Firebase
        lastUpdateToFirebase = now;
        print('&&&&&&&&&Firestore Insert ON &&&&&&&&&&');

      } else {
        bg.BackgroundGeolocation.setConfig(bg.Config(maxRecordsToPersist: 0)); // don't store this point
        print('&&&&&&&&&Firestore Insert OFF &&&&&&&&&&');
      }
    }

But see the attached log, which seems to show:

Testing on a real Android device indicates I am still getting all locations sent to Firebase.

Your insights would be appreciated.

MapRunF Log - Firebase v1.txt

christocracy commented 4 years ago

Set it 0 and keep it 0. You’ll find nothing gets persisted.

fne00 commented 4 years ago

But if I do that, won't I get no locations sent to Firebase? I still want a location sent every 10 seconds.

christocracy commented 4 years ago

I’m asking you to do a test, to perform an extreme case and determine the outcome.

fne00 commented 4 years ago

OK - Sorry - my misunderstanding.

I have set both branches of the if statement to: bg.BackgroundGeolocation.setConfig(bg.Config(maxRecordsToPersist: 0))

All locations are still being sent to Firebase...!

christocracy commented 4 years ago

You needn’t provide exclamations (!). Just provide the facts and I’ll look into it.

fne00 commented 4 years ago

OK not meaning to imply anything.

Just is case it's relevant, in my initial bg.config I have:

      bgConfigToApply = bg.Config(
          persistMode: saveToBGsqlDBandLiveTrack,
         .....

where

    int saveToBGsqlDBandLiveTrack = liveFireStoreEnabled
        ? bg.Config.PERSIST_MODE_ALL
        : bg.Config.PERSIST_MODE_NONE;
fne00 commented 4 years ago

Chris,

I've changed my manual throttling of location updates to Cloud Firestore, to the following.

    // handle throttling updates to Firebase
    if (liveFireStoreEnabled)  {
      DateTime now = DateTime.now();
      if(now.isAfter(lastUpdateToFirebase.add(Duration(seconds: liveFireStoreInterval ))))
      {
        bg.BackgroundGeolocation.setConfig(bg.Config(persistMode: bg.Config.PERSIST_MODE_ALL)); // store point(s) to SQL and Firebase
        lastUpdateToFirebase = now;
        print('&&&&&&&&&Firestore Insert ON &&&&&&&&&&');
      } else {
        bg.BackgroundGeolocation.setConfig(bg.Config(persistMode: bg.Config.PERSIST_MODE_NONE)); // don't store to SQL/Firebase
        print('&&&&&&&&&Firestore Insert OFF &&&&&&&&&&');
      }
    }

Testing so far indicates that this is working. That is:

My questions is:

Thanks

fne00 commented 4 years ago

Chris, I appreciate that my question above is not top of your priority list, so I've deployed this solution to my production App anyway. It seems to work OK. One implication I can see from this approach is, that when the user drops off line, I am effectively discarding the data. So the solution is not ideal. Would you consider my original post on this issue to be an enhancement request please. (or other suggestions are welcome). Thanks

christocracy commented 4 years ago

Yes, but I won’t be able to get around to starting on this this for at least a month.

fne00 commented 4 years ago

OK - thanks - no problems - I'll look forward to it in due course.

fne00 commented 4 years ago

Chris, Is this still in your forward plans? I certainly would find it valuable for my MapRunF App, and I can't think of a way to achieve the outcome without a change in this Package. Thanks

fne00 commented 3 years ago

Chris, Is this in your current plans? Anything I can do to assist? (I'm assuming it would require changes on the native end(s) - which is why I haven't tried to adapt your Dart code).

Context: My MapRunF App is being used by runners for 8,000-10,000 runs per month. Some organising clubs would like live tracking...but if I push all data to Firebase, I get too much data. With my current approach to culling the data (as above), I lose data if there is no data connection. I guess I could revert to sending all data from the App to Firebase and then culling it there with a Firebase Function ... but I could incur higher usage charges from Google. Thanks Peter

christocracy commented 3 years ago

What's wrong with the solution you posted above using persistMode?

fne00 commented 3 years ago

Chris,

I'm pretty sure that when I do: bg.BackgroundGeolocation.setConfig(bg.Config(persistMode: bg.Config.PERSIST_MODE_NONE));

any data queued up in the internal SQL database (that hasn't been sent to Firebase) will be discarded. This is OK if the device is always online (as I assume lost data would be minimal), but for the types of events we run, that can't be assumed.

Peter

christocracy commented 3 years ago

any data queued up in the internal SQL database (that hasn't been sent to Firebase) will be discarded

When you activate the Firebase Adapter, persistence to background-geolocation's SQLite database is disabled. Firebase automatically handles on-device queuing of data when there's no network connection.

fne00 commented 3 years ago

Thanks - Looks like I have made incorrect assumptions, and so my current approach of throttling updates to Firebase may well be adequate. I'll do some more thorough testing.

mrruby commented 3 years ago

@christocracy Any update on this? I am looking for the same behavior of sending location into the database with an interval of not less than 20 minutes.

Setting persistMode approach is ok?

christocracy commented 3 years ago

Config.persistMode is a flag. Whenever a location or geofence event occurs, BackgroundGeolocation evaluates that flag when deciding whether to broadcast that location/geofence event on to the Firebase adapter.

You are free to switch that persistMode flag at any time and however often your wish.