react-native-background-geolocation icon indicating copy to clipboard operation
react-native-background-geolocation copied to clipboard

Setting a schedule outside of the current time does not disable tracking on iOS

Open albertstill opened this issue 1 year ago • 5 comments

Please note I don't see this issue on Android.

Side note: I'm also also seeing a seperate issue that may be related to this one where by the app is tracking users outside of their tracking schedule on iOS. I've noticed it as well as my app's users.

Your Environment

  • Plugin version: 4.14.5
  • Platform: iOS
  • OS version: 17.2
  • Device manufacturer / model: Apple
  • React Native version (react-native -v): 0.71.14
  • Plugin config
  // setting the schedue/config
  await BackgroundGeolocation.setConfig({
      distanceFilter: 25,
      stopOnTerminate: false,
      startOnBoot: true,
      foregroundService: true,

      schedule: scheduleArray,

      // Android
      notification: {
        title: 'Tern',
        text: 'Detecting when you cycle, walk and run to work.',
        channelName: 'Active commute detection',
        color: BRAND_COLOR,
        smallIcon: 'drawable/ic_stat_ic_notification',
        largeIcon: 'drawable/ic_stat_ic_notification',
        priority: BackgroundGeolocation.NOTIFICATION_PRIORITY_MIN,
      },

      // http options
      url: `${TRACKING_ENDPOINT}${userId}`,
      params: {
        device: {
          uuid: deviceInfo.getModel().replace(/[\s.,]/g, '-'),
          model: deviceInfo.getModel(),
          platform: deviceInfo.getSystemName(),
          manufacturer: await deviceInfo.getManufacturer(),
          version: deviceInfo.getSystemVersion(),
          framework: 'ReactNative',
        },
      },
      autoSyncThreshold: 20,
      batchSync: true,
      maxBatchSize: 60,

      showsBackgroundLocationIndicator: true,
    });
    
    /// the handler 
    BackgroundGeolocation.onEnabledChange(isEnabled => {
        if (webViewRef.current) {
          webViewRef.current.injectJavaScript(
            generateJS('updateIsTracking', isEnabled),
          );
        }
      });

Expected Behavior

When setting a schedule outside of the current time, tracking is disabled, the onEnabledChange event fires, triggering the UI to update showing tracking is disabled.

Actual Behavior

Tracking is not disabled, no onEnabledChange event fires, the UI continues to show tracking enabled (See video).

Steps to Reproduce

Imagine it's a Tuesday

  1. BackgroundGeolocation.setConfig is called with the below config, the schedule array indicates today (Tuesday):
{
  "logLevel": 5,
  "debug": true,
  "distanceFilter": 25,
  "stopOnTerminate": false,
  "startOnBoot": true,
  "foregroundService": true,
  "schedule": [
    "3 00:01-00:00"
  ],
  "notification": {
    "title": "Tern",
    "text": "Detecting when you cycle, walk and run to work.",
    "channelName": "Active commute detection",
    "color": "#4caf50",
    "smallIcon": "drawable/ic_stat_ic_notification",
    "largeIcon": "drawable/ic_stat_ic_notification",
    "priority": -2
  },
  "url": "http://localhost:3000/locations/988",
  "params": {
    "device": {
      "uuid": "iPhone",
      "model": "iPhone",
      "platform": "iOS",
      "manufacturer": "Apple",
      "version": "17.2",
      "framework": "ReactNative"
    }
  },
  "autoSyncThreshold": 20,
  "batchSync": true,
  "maxBatchSize": 60,
  "showsBackgroundLocationIndicator": true
}

This fires onEnabledChange and the UI reflects tracking enabled.

  1. User triggers a schedule update, same config as above but now with scheduleArray: ["3 00:01-00:00", "4 00:01-00:00"], tracking state remains enabled.
  2. User removes today from schedule array with scheduleArray: ["4 00:01-00:00"], this should disable tracking but the tracking state remains enabled.

Working turning on and then off for a single day

https://github.com/transistorsoft/react-native-background-geolocation/assets/2787876/0f575a50-8585-4924-aad5-aed650c4eda8

Problem with it going on and not turning off

https://github.com/transistorsoft/react-native-background-geolocation/assets/2787876/25c96e6b-19c7-4adf-853e-bb508e50b1ff

Context

The product goal is to allow the user to set their tracking schedule, the app does not support a start/stop button, therefore the tracking schedule is the only way they start and stop RNBG.

Debug logs

Logs
'scheduleArray:', [ '3 00:01-00:00' ]
'config:', '{\n  "logLevel": 5,\n  "debug": true,\n  "distanceFilter": 25,\n  "stopOnTerminate": false,\n  "startOnBoot": true,\n  "foregroundService": true,\n  "schedule": [\n    "3 00:01-00:00"\n  ],\n  "notification": {\n    "title": "Tern",\n    "text": "Detecting when you cycle, walk and run to work.",\n    "channelName": "Active commute detection",\n    "color": "#4caf50",\n    "smallIcon": "drawable/ic_stat_ic_notification",\n    "largeIcon": "drawable/ic_stat_ic_notification",\n    "priority": -2\n  },\n  "url": "http://localhost:3000/locations/988",\n  "params": {\n    "device": {\n      "uuid": "iPhone",\n      "model": "iPhone",\n      "platform": "iOS",\n      "manufacturer": "Apple",\n      "version": "17.2",\n      "framework": "ReactNative"\n    }\n  },\n  "autoSyncThreshold": 20,\n  "batchSync": true,\n  "maxBatchSize": 60,\n  "showsBackgroundLocationIndicator": true\n}'

╔═══════════════════════════════════════════════════════════
║ -[TSHttpService flush:] 
╚═══════════════════════════════════════════════════════════

╔═══════════════════════════════════════════════════════════
║ -[TSScheduler parse:] 
(
    "TSSchedule[triggered: 0, 0:1 - 0:0, Days:3, trackingMode: 1]"
)
╚═══════════════════════════════════════════════════════════
ℹ️-[TSConfig persist]

╔═══════════════════════════════════════════════════════════
║ -[TSHttpService finish:error:] Success: 1
╚═══════════════════════════════════════════════════════════
🎾-[TSScheduler start] ON
ℹ️-[TSConfig persist]

╔═══════════════════════════════════════════════════════════
║ -[TSScheduler findNextSchedule:] Day #3
╚═══════════════════════════════════════════════════════════
✅-[TSScheduler findNextSchedule:] Found schedule: TSSchedule[triggered: 0, 0:1 - 0:0, Days:3, trackingMode: 1]
✅-[TSSchedule trigger:] ON

╔═══════════════════════════════════════════════════════════
║ -[TSScheduler handleEvent:] Schedule: TSSchedule[triggered: 1, 0:1 - 0:0, Days:3, trackingMode: 1]
╚═══════════════════════════════════════════════════════════
🔵-[TSLocationManager createSchedulerHandler]_block_invoke 📅Scheduler block fired: enabled: 0 | Trigger: 1 | TSSchedule[triggered: 1, 0:1 - 0:0, Days:3, trackingMode: 1]
ℹ️-[TSLocationManager doStart:] trackingMode: 1
ℹ️-[TSConfig persist]
'onEnabledChange isEnabled:', true
🎾-[TSGeofenceManager start]
🔵-[TSLocationManager setPace:] 0
🎾-[TSLocationManager startUpdatingLocation] Location-services: ON
🎾-[TSLocationManager startMonitoringSignificantLocationChanges]
ℹ️-[PolygonGeofencingService setLocation:] Already updating location <IGNORED>

╔═══════════════════════════════════════════════════════════
║ -[TSHttpService flush:] 
╚═══════════════════════════════════════════════════════════

╔═══════════════════════════════════════════════════════════
║ -[TSHttpService finish:error:] Success: 1
╚═══════════════════════════════════════════════════════════
ℹ️+[LocationAuthorization run:onCancel:] status: 3
🎾-[TSLocationManager startMonitoringBackgroundFetch] BackgroundFetch: ON
🎾-[TSLocationManager startMonitoringBackgroundFetch] BackgroundFetch: ON
🔵-[TSScheduler evaluate] TSSchedule[triggered: 1, 0:1 - 0:0, Days:3, trackingMode: 1]

📍<+37.78583400,-122.40641700> +/- 5.00m (speed -1.00 mps / course -1.00) @ 26/12/2023, 7:23:21 pm Greenwich Mean Time

╔═══════════════════════════════════════════════════════════
║ -[TSLocationManager locationManager:didUpdateLocations:] Enabled: 1 | isMoving: 0 | df: -1.0m | age: 101 ms
╚═══════════════════════════════════════════════════════════
✅-[TSLocationManager locationManager:didUpdateLocations:] Acquired motionchange position: <+37.78583400,-122.40641700> +/- 5.00m (speed -1.00 mps / course -1.00) @ 26/12/2023, 7:23:21 pm Greenwich Mean Time
🔵-[TSLocationManager startMonitoringStationaryRegion:radius:] Radius: 200
🔴-[TSLocationManager stopUpdatingLocation]
🔵-[TSLocationManager calculateMedianLocationAccuracy:] Median location accuracy: 5.0
ℹ️-[PolygonGeofencingService setLocation:] Already updating location <IGNORED>
✅-[TSLocationManager persistLocation:]_block_invoke INSERT: 00E7AD24-DFCA-4EB8-92A5-8C3D79272FDF
[TSBackgroundFetch scheduleBGAppRefresh] com.transistorsoft.fetch
ℹ️-[TSLocationManager startMonitoringBackgroundFetch]_block_invoke Configured BackgroundFetch

╔═══════════════════════════════════════════════════════════
║ -[TSHttpService flush:] 
╚═══════════════════════════════════════════════════════════
✅-[BackgroundTaskManager createBackgroundTask] 44
🔵-[LocationDAO allWithLocking:]_block_invoke LOCKED 1 RECORDS
🔵-[TSHttpService postBatch:] 1 records
nw_socket_handle_socket_event [C15.1.1:2] Socket SO_ERROR [61: Connection refused]
🔵-[HttpResponse handleResponse] Response: 200
✅-[LocationDAO destroyAll:] DESTROY: 00E7AD24-DFCA-4EB8-92A5-8C3D79272FDF
✅-[LocationDAO destroyAll:]_block_invoke DESTROY SUCCESS (1)
🔵-[LocationDAO allWithLocking:]_block_invoke LOCKED 0 RECORDS

╔═══════════════════════════════════════════════════════════
║ -[TSHttpService finish:error:] Success: 1
╚═══════════════════════════════════════════════════════════
✅-[BackgroundTaskManager stopBackgroundTask:]_block_invoke 44 OF (
    44
)
'scheduleArray:', [ '3 00:01-00:00', '4 00:01-00:00' ]
'config:', '{\n  "logLevel": 5,\n  "debug": true,\n  "distanceFilter": 25,\n  "stopOnTerminate": false,\n  "startOnBoot": true,\n  "foregroundService": true,\n  "schedule": [\n    "3 00:01-00:00",\n    "4 00:01-00:00"\n  ],\n  "notification": {\n    "title": "Tern",\n    "text": "Detecting when you cycle, walk and run to work.",\n    "channelName": "Active commute detection",\n    "color": "#4caf50",\n    "smallIcon": "drawable/ic_stat_ic_notification",\n    "largeIcon": "drawable/ic_stat_ic_notification",\n    "priority": -2\n  },\n  "url": "http://localhost:3000/locations/988",\n  "params": {\n    "device": {\n      "uuid": "iPhone",\n      "model": "iPhone",\n      "platform": "iOS",\n      "manufacturer": "Apple",\n      "version": "17.2",\n      "framework": "ReactNative"\n    }\n  },\n  "autoSyncThreshold": 20,\n  "batchSync": true,\n  "maxBatchSize": 60,\n  "showsBackgroundLocationIndicator": true\n}'

╔═══════════════════════════════════════════════════════════
║ -[TSScheduler parse:] 
(
    "TSSchedule[triggered: 0, 0:1 - 0:0, Days:3, trackingMode: 1]",
    "TSSchedule[triggered: 0, 0:1 - 0:0, Days:4, trackingMode: 1]"
)
╚═══════════════════════════════════════════════════════════

╔═══════════════════════════════════════════════════════════
║ -[TSScheduler findNextSchedule:] Day #3
╚═══════════════════════════════════════════════════════════
✅-[TSScheduler findNextSchedule:] Found schedule: TSSchedule[triggered: 0, 0:1 - 0:0, Days:3, trackingMode: 1]
✅-[TSSchedule trigger:] ON

╔═══════════════════════════════════════════════════════════
║ -[TSScheduler handleEvent:] Schedule: TSSchedule[triggered: 1, 0:1 - 0:0, Days:3, trackingMode: 1]
╚═══════════════════════════════════════════════════════════
🔵-[TSLocationManager createSchedulerHandler]_block_invoke 📅Scheduler block fired: enabled: 1 | Trigger: 1 | TSSchedule[triggered: 1, 0:1 - 0:0, Days:3, trackingMode: 1]
ℹ️-[TSLocationManager doStart:] trackingMode: 1
ℹ️-[TSLocationManager loadLastOdometerLocation] <+37.78583400,-122.40641700> +/- -1.00m (speed -1.00 mps / course -1.00) @ 26/12/2023, 7:23:25 pm Greenwich Mean Time
🎾-[TSGeofenceManager start]
🔵-[TSLocationManager setPace:] 0

╔═══════════════════════════════════════════════════════════
║ -[TSHttpService flush:] 
╚═══════════════════════════════════════════════════════════

╔═══════════════════════════════════════════════════════════
║ -[TSHttpService finish:error:] Success: 1
╚═══════════════════════════════════════════════════════════
🎾-[TSLocationManager startUpdatingLocation] Location-services: ON
ℹ️+[LocationAuthorization run:onCancel:] status: 3
🎾-[TSLocationManager startMonitoringBackgroundFetch] BackgroundFetch: ON
ℹ️-[TSConfig persist]
🎾-[TSLocationManager startMonitoringSignificantLocationChanges]
🎾-[TSLocationManager startMonitoringBackgroundFetch] BackgroundFetch: ON
🔵-[TSScheduler evaluate] TSSchedule[triggered: 1, 0:1 - 0:0, Days:3, trackingMode: 1]

📍<+37.78583400,-122.40641700> +/- 5.00m (speed -1.00 mps / course -1.00) @ 26/12/2023, 7:23:25 pm Greenwich Mean Time

╔═══════════════════════════════════════════════════════════
║ -[TSLocationManager locationManager:didUpdateLocations:] Enabled: 1 | isMoving: 0 | df: -1.0m | age: 249 ms
╚═══════════════════════════════════════════════════════════
✅-[TSLocationManager locationManager:didUpdateLocations:] Acquired motionchange position: <+37.78583400,-122.40641700> +/- 5.00m (speed -1.00 mps / course -1.00) @ 26/12/2023, 7:23:25 pm Greenwich Mean Time
🔵-[TSLocationManager startMonitoringStationaryRegion:radius:] Radius: 200
🔴-[TSLocationManager stopUpdatingLocation]
🔵-[TSLocationManager calculateMedianLocationAccuracy:] Median location accuracy: 5.0
ℹ️-[PolygonGeofencingService setLocation:] Already updating location <IGNORED>
✅-[TSLocationManager persistLocation:]_block_invoke INSERT: 7797C2A0-D686-4FAD-900C-ED5E63F88B3C

╔═══════════════════════════════════════════════════════════
║ -[TSHttpService flush:] 
╚═══════════════════════════════════════════════════════════
✅-[BackgroundTaskManager createBackgroundTask] 45
🔵-[LocationDAO allWithLocking:]_block_invoke LOCKED 1 RECORDS
🔵-[TSHttpService postBatch:] 1 records
nw_socket_handle_socket_event [C16.1.1:2] Socket SO_ERROR [61: Connection refused]
🔵-[HttpResponse handleResponse] Response: 200
✅-[LocationDAO destroyAll:] DESTROY: 7797C2A0-D686-4FAD-900C-ED5E63F88B3C
✅-[LocationDAO destroyAll:]_block_invoke DESTROY SUCCESS (1)
🔵-[LocationDAO allWithLocking:]_block_invoke LOCKED 0 RECORDS

╔═══════════════════════════════════════════════════════════
║ -[TSHttpService finish:error:] Success: 1
╚═══════════════════════════════════════════════════════════
✅-[BackgroundTaskManager stopBackgroundTask:]_block_invoke 45 OF (
    45
)
'scheduleArray:', [ '4 00:01-00:00' ]
'config:', '{\n  "logLevel": 5,\n  "debug": true,\n  "distanceFilter": 25,\n  "stopOnTerminate": false,\n  "startOnBoot": true,\n  "foregroundService": true,\n  "schedule": [\n    "4 00:01-00:00"\n  ],\n  "notification": {\n    "title": "Tern",\n    "text": "Detecting when you cycle, walk and run to work.",\n    "channelName": "Active commute detection",\n    "color": "#4caf50",\n    "smallIcon": "drawable/ic_stat_ic_notification",\n    "largeIcon": "drawable/ic_stat_ic_notification",\n    "priority": -2\n  },\n  "url": "http://localhost:3000/locations/988",\n  "params": {\n    "device": {\n      "uuid": "iPhone",\n      "model": "iPhone",\n      "platform": "iOS",\n      "manufacturer": "Apple",\n      "version": "17.2",\n      "framework": "ReactNative"\n    }\n  },\n  "autoSyncThreshold": 20,\n  "batchSync": true,\n  "maxBatchSize": 60,\n  "showsBackgroundLocationIndicator": true\n}'

╔═══════════════════════════════════════════════════════════
║ -[TSScheduler parse:] 
(
    "TSSchedule[triggered: 0, 0:1 - 0:0, Days:4, trackingMode: 1]"
)
╚═══════════════════════════════════════════════════════════

╔═══════════════════════════════════════════════════════════
║ -[TSScheduler findNextSchedule:] Day #3
╚═══════════════════════════════════════════════════════════
🔵-[TSScheduler findNextSchedule:] Failed to find schedule for this day.  Will retry tomorrow.
ℹ️-[TSConfig persist]
🎾-[TSLocationManager startMonitoringSignificantLocationChanges]
🎾-[TSLocationManager startMonitoringBackgroundFetch] BackgroundFetch: ON

albertstill avatar Dec 26 '23 19:12 albertstill

Why do you use such an odd time of 00:01-00:00?

A day begins at 00:00 and the last minute of the day is 00:59.

christocracy avatar Jan 08 '24 23:01 christocracy

hey Chris

Screenshot 2024-01-09 at 6 54 49 pm

I wasn't 100% what to do for whole day tracking, but because the docs give an example of "2,4,6 20:00-00:00",// Mon, Web, Fri: 8pm to midnight (next day), I assumed 00:00 meant midnight of that evening.

I've changed it to 00:00-23:59 to represent whole day tracking but the same issue happens, any ideas?

thanks

albertstill avatar Jan 09 '24 22:01 albertstill

In the demo app, with the plugin currently enabled (State.enabled == true), I add a schedule 1-7 17:00-20:00 and call .startSchedule(). The time is currently 12:46 pm, so the schedule is "outside of the current time".

Here are the logs:

╔═══════════════════════════════════════════════════════════
║ -[TSScheduler parse:] 
(
    "TSSchedule[triggered: 0, 17:0 - 20:0, Days:1,2,3,4,5,6,7, trackingMode: 1]"
)
╚═══════════════════════════════════════════════════════════

╔═══════════════════════════════════════════════════════════
║ -[TSScheduler findNextSchedule:] Day #6
╚═══════════════════════════════════════════════════════════
✅-[TSScheduler findNextSchedule:] Found schedule: TSSchedule[triggered: 0, 17:0 - 20:0, Days:1,2,3,4,5,6,7, trackingMode: 1]
🔴-[TSSchedule trigger:] OFF

╔═══════════════════════════════════════════════════════════
║ -[TSScheduler handleEvent:] Schedule: TSSchedule[triggered: 0, 17:0 - 20:0, Days:1,2,3,4,5,6,7, trackingMode: 1]
╚═══════════════════════════════════════════════════════════
 [enabledchange] - false <------------------- ENABLEDCHANGE DOES FIRE.

Calling .startSchedule() caused the plugin to be disabled.

christocracy avatar Jan 12 '24 17:01 christocracy

thanks @christocracy

I think I've solved the issue by stopping the existing schedule before starting a new updated one.

I thought I could update the schedule with setConfig once I had run startSchedule, and it would just adjust it accordingly.

My new schedule update handler code looks like this, where I always stop the existing schedule (and disable if enabled) before setting a new schedule.

const state = await BackgroundGeolocation.stopSchedule();
if (state.enabled) {
  await BackgroundGeolocation.stop();
}
  
await BackgroundGeolocation.setConfig({
  ...
  schedule: newScheduleArray,
})
    
await BackgroundGeolocation.startSchedule();

this now means my UI "tracking status" bar which reacts to onEnabledChange updates perfectly when the schedule is edited, thanks!

the issue I'm having now is around the app tracking outside of the schedule, which in my case is day based, I'm using the X 00:00-23:59 time.

When testing in a real build, I'm finding the app tracking the day after even if it's outside of the schedule, and does not have that day enabled.

So if the user set it to Sunday only tracking, and the RNBG schedule array was ['1 00:00-23:59']. Then I see the plugin track on Sunday, but on the Monday I also find it's also tracking with location data being received on the server. And it's not until I open the app settings page and reload the schedule that it turns off tracking. Any ideas? Is an array of X 00:00-23:59 strings an appropriate way to do day on/off schedule tracking?

cheers

albertstill avatar Jan 28 '24 08:01 albertstill

Still working on a fix for my last message. The app still seems to track the day after even though it's only enabled to track the day before.

My root component runs the following .ready code but looking at the docs that looks correct?

useEffect(() => {
    async function execute() {
      await BackgroundGeolocation.ready({
        reset: false,
      });

      BackgroundGeolocation.onEnabledChange(isEnabled => {
        if (webViewRef.current) {
          webViewRef.current.injectJavaScript(
            generateJS('updateIsTracking', isEnabled),
          );
        }
      });
    }

    execute();
  }, []);

any ideas @christocracy ?

albertstill avatar Feb 03 '24 07:02 albertstill

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar Apr 18 '24 01:04 github-actions[bot]

This issue was closed because it has been inactive for 14 days since being marked as stale.

github-actions[bot] avatar May 02 '24 01:05 github-actions[bot]