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

Clarity on how config is applied with BackgroundGeolocation.ready()

Open ascherkus opened this issue 2 years ago • 4 comments

Your Environment

  • Plugin version: 4.12.1
  • Platform: iOS
  • OS version: 16.2
  • Device manufacturer / model: Simulator
  • React Native version (react-native -v): 0.66.5
  • Plugin config
{
  "batchSync": true,
  "didDeviceReboot": false,
  "desiredAccuracy": -1,
  "autoSync": true,
  "stopDetectionDelay": 0,
  "didLaunchInBackground": false,
  "enableTimestampMeta": false,
  "startOnBoot": false,
  "disableStopDetection": false,
  "activityType": 1,
  "disableAutoSyncOnCellular": false,
  "debug": false,
  "autoSyncThreshold": 20,
  "stopTimeout": 5,
  "locationAuthorizationRequest": "WhenInUse",
  "geofenceTemplate": "",
  "stopOnStationary": false,
  "isFirstBoot": false,
  "disableElasticity": false,
  "httpTimeout": 60000,
  "stopOnTerminate": false,
  "desiredOdometerAccuracy": 100,
  "didRequestUpgradeLocationAuthorization": false,
  "headers": {
    "Authorization": "Bearer foo"
  },
  "maxRecordsToPersist": -1,
  "activityRecognitionInterval": 10000,
  "locationAuthorizationAlert": {
    "settingsButton": "Settings",
    "instructions": "To use background location, you must enable '{locationAuthorizationRequest}' in the Location Services settings",
    "titleWhenNotEnabled": "Background location is not enabled",
    "cancelButton": "Cancel",
    "titleWhenOff": "Location services are off"
  },
  "isMoving": false,
  "trackingMode": 1,
  "stationaryRadius": 25,
  "params": {},
  "extras": {},
  "elasticityMultiplier": 1,
  "disableLocationAuthorizationAlert": false,
  "httpRootProperty": "locations",
  "preventSuspend": false,
  "disableMotionActivityUpdates": false,
  "logMaxDays": 3,
  "lastLocationAuthorizationStatus": 0,
  "heartbeatInterval": 60,
  "useSignificantChangesOnly": false,
  "odometer": 0,
  "locationTimeout": 30,
  "showsBackgroundLocationIndicator": true,
  "minimumActivityRecognitionConfidence": 70,
  "geofenceInitialTriggerEntry": true,
  "schedulerEnabled": false,
  "method": "POST",
  "iOSHasWarnedLocationServicesOff": false,
  "maxBatchSize": 200,
  "url": "https://foo/bar",
  "distanceFilter": 10,
  "locationsOrderDirection": "ASC",
  "persistMode": 2,
  "stopAfterElapsedMinutes": -1,
  "enabled": false,
  "schedule": [],
  "authorization": {},
  "pausesLocationUpdatesAutomatically": true,
  "geofenceProximityRadius": 2000,
  "maxDaysToPersist": 1,
  "logLevel": 0
}

Expected Behavior

Based on my interpretation of the following documentation:

The supplied [[Config]] will be applied only at first install of your app — for every launch thereafter, the plugin will automatically load its last-known configuration from persistent storage. The plugin always remembers the configuration you apply to it.

... I was expecting that on subsequent launches that when ready() is called with our standard config that it would be entirely ignored (because it's only applied at first install and is automatically loaded) or perhaps even merged with the last known configuration.

As per the documentation I would assume reset() or setConfig() would be used to explicitly overwrite the last-known configuration.

Actual Behavior

In our application we use headers and extras when recording a particular route, however our default config that comes bundled with our application that we use to initialize the SDK doesn't include headers or extras because at first install and launch we haven't started anything yet.

As a result, calling ready() with our default configuration clears headers and extras. This becomes and issue when using stopOnTerminate: false on iOS since we'll end up clearing our authentication headers and extras.

Steps to Reproduce

  1. In app launch code, initialize the SDK with ready({stopOnTerminate: false})
  2. Start tracking by calling setConfig({extras: {foo: "bar"}) followed by start()
  3. Terminate the app
  4. Wait for iOS to relaunch the app. The call to ready({stopOnTerminate: false}) clears the extras on subsequent locations being recorded

You can also verify the before/after state by calling getState() before and after ready() to see extras get cleared.

Context

Ensure that my authorization headers and extras are persistend even when iOS relaunches my application for background tracking.

I can work around this by calling getState() before calling ready() and doing a manual merge of my config ... but I'd like to hear what the proper expectation and use of ready() should be for this particular use case.

Thanks!

ascherkus avatar Oct 17 '23 19:10 ascherkus

Do not use reset: false

The config is applied each time .ready is called.

christocracy avatar Oct 17 '23 19:10 christocracy

Thanks for the quick reply. That clears things up and matches what I tested.

We're not using reset: false but reading through the documentation more ... isn't the documentation for ready() misleading given default config value of reset: true?

Compare ready()

The supplied [[Config]] will be applied only at first install of your app

vs. reset:

Controls whether the plugin should first reset the configuration when #ready is executed before applying the supplied config {}. Defaults to true.

My reading of ready() would imply that reset: false is the default behaviour when in fact it's not.

Am I just misinterpreting something here?

ascherkus avatar Oct 17 '23 20:10 ascherkus

Your config is re-applied each time .ready is called.

christocracy avatar Oct 17 '23 20:10 christocracy

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

github-actions[bot] avatar May 03 '24 01:05 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 18 '24 01:05 github-actions[bot]

Sorry to come back to this issue... But I have exactly the same situation as the OP. And I can solve it be using reset: false in my default config (calling ready()). But you keep saying that almost nobody should use reset: false... Leaving it out (i.e. using default reset: true), my updated config (after ready(), exact same use case as OP with headers & params) is NOT merged and only the default config (from the ready() call) is applied. So the tracking data is not correctly send to my server (as the auth and some extra data are missing).

sbeigel avatar Jun 10 '24 15:06 sbeigel