transistorsoft / react-native-background-geolocation

Sophisticated, battery-conscious background-geolocation with motion-detection
http://shop.transistorsoft.com/pages/react-native-background-geolocation
MIT License
2.54k stars 424 forks source link

[SOLVED] Suddenly getting a location unknown error #1992

Closed christian-hess-94 closed 1 month ago

christian-hess-94 commented 1 month ago

SOLUTION: The issue was fixed when:

Your Environment

Expected Behavior

We want to be able to use the plugin to automatically send location updates to provided URL We want to be able to manually retrive location data when running BackgroundGeolocation.getCurrentPosition()

Actual Behavior

The plugin is not sending the automatic location updates. Also when using mapbox, the GPS location marker does not appear rendered in the map, as if it were unavailable When running BackgroundGeolocation.getCurrentPosition (after running BackgroundGeolocation.ready()) we get the 0 error that stands for location unknown

Steps to Reproduce

  1. Run BackgroundGeolocation.ready() on app start
useEffect(() => {
    BackgroundGeolocation.ready({
      ...composeLocationTrackingConfigSignificantOn(userSession), //returns config object
    }).then(async state => {
      logger.debug('- BackgroundGeolocation state: ', state);
      if (!state.enabled) {
        const {
          backgroundLocationGranted,
          fineLocationGranted,
        } = await verifyPermissionStatus({ onPermissionsNotGranted() {} });
        if (
          backgroundLocationGranted &&
          fineLocationGranted
        ) {
          BackgroundGeolocation.start(); //run start after plugin is ready
          if (ENV === 'DEVELOPMENT') {
            Toast.show({
              type: 'error',
              text1: `Plugin is NOT ready, starting`,
              visibilityTime: 1000,
            });
          }
        }
      }
      if (ENV === 'DEVELOPMENT' && state.enabled) {
        Toast.show({
          type: 'success',
          text1: `Plugin is ready and enabled`,
          visibilityTime: 1000,
        });
      }
    });
  }, []);
  1. After, load the map using mapbox, no GPS marker shows up
  2. At specific times, manually call BackgroundGeolocation.getCurrentPosition()

    const {
    backgroundLocationGranted,
    coarseLocationGranted,
    fineLocationGranted,
    } = await verifyPermissionStatus({});
    
    if (
    backgroundLocationGranted &&
    coarseLocationGranted &&
    fineLocationGranted
    ) {
    const currentPosition = await BackgroundGeolocation.getCurrentPosition({
      desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH,
    });
    const route = `/providers/${providerId}/location`;
    const location: [Location] = [{ ...currentPosition }];
    await AxiosApiInstance.post(
      route,
      { location },
      {
        headers: {
          'X-TUP-Auth-Version': '1',
        },
      }
    );
    }

Context

## Debug logs
<!-- include iOS / Android logs
- ios XCode logs,
- use #getLog #emailLog methods (@see docs)
- Android: $ adb logcat -s TSLocationManager
-->
<details><summary>Logs</summary>

``` <!-- Syntax highlighting:  DO NOT REMOVE -->
we do not get any logs, the plugin simply fails to recognize the device's location (both iPhone 15 simulator and physical iPhone 11 device)

christocracy commented 1 month ago

I suggest you launch your app in XCode and carefully monitor the logs.

this is not a plugin issue. This an issue with your app or device settings.

christian-hess-94 commented 1 month ago

thanks for the quick response! I'll run it and see if the logs can give any more info

christian-hess-94 commented 1 month ago

After running the app and observing the logs we are receiving this error:

This method can cause UI unresponsiveness if invoked on the main thread. Instead, consider waiting for the -locationManagerDidChangeAuthorization: callback and checking authorizationStatus first. This method can cause UI unresponsiveness if invoked on the main thread. Instead, consider waiting for the -locationManagerDidChangeAuthorization: callback and checking authorizationStatus first.

christian-hess-94 commented 1 month ago

also this: image

christian-hess-94 commented 1 month ago

image

christocracy commented 1 month ago

This method can cause UI unresponsiveness if invoked on the main thread. Instead, consider waiting for the -locationManagerDidChangeAuthorization: callback and checking authorizationStatus first.

You are likely using some other plugin responsible for that.

Here is the entire logs of my demo app launching:

XCode boot logs ``` [TSBackgroundFetch load]: ( ) [TSBGAppRefreshSubscriber load]: { TSLocationManager = ""; "react-native-background-fetch" = ""; } [TSBackgroundFetch registerForTaskWithIdentifier: com.transistorsoft.customtask Running application BGGeolocation ({ initialProps = { }; rootTag = 1; }) ℹ️-[TSDBLogger db_delete] maxAge: 259200 Unbalanced calls start/end for tag 19 Running "BGGeolocation '[onEnabledChange]', false [Authorization registerTransistorAuthorizationHandler] πŸ”‘ Found cached TransistorAuthorizationToken for host tracker.transistorsoft.com '[onEnabledChange]', true ℹ️-[TSLocationManager init] ╔═════════════════════════════════════════════ β•‘ TSLocationManager (build 388) ╠══════════════════════════════════════════════ { activityRecognitionInterval = 10000; activityType = 1; authorization = { accessToken = "eyJhb"; expires = "-1"; refreshHeaders = { Authorization = "Bearer {accessToken}"; }; refreshPayload = { "refresh_token" = "{refreshToken}"; }; refreshToken = "cd4f7"; refreshUrl = "https://tracker.transistorsoft.com/api/refresh_token"; strategy = JWT; }; autoSync = 1; autoSyncThreshold = 0; batchSync = 0; debug = 0; desiredAccuracy = "-1"; desiredOdometerAccuracy = 100; didDeviceReboot = 0; didLaunchInBackground = 0; didRequestUpgradeLocationAuthorization = 1; disableAutoSyncOnCellular = 0; disableElasticity = 0; disableLocationAuthorizationAlert = 0; disableMotionActivityUpdates = 0; disableStopDetection = 0; distanceFilter = 50; elasticityMultiplier = 1; enableTimestampMeta = 0; enabled = 1; extras = { }; geofenceInitialTriggerEntry = 1; geofenceProximityRadius = 2000; geofenceTemplate = ""; headers = { }; heartbeatInterval = 900; httpRootProperty = location; httpTimeout = 60000; iOSHasWarnedLocationServicesOff = 1; isFirstBoot = 0; isMoving = 0; lastLocationAuthorizationStatus = 3; locationAuthorizationAlert = { cancelButton = Cancel; instructions = "To use background location, you must enable '{locationAuthorizationRequest}' in the Location Services settings"; settingsButton = Settings; titleWhenNotEnabled = "Background location is not enabled"; titleWhenOff = "Location services are off"; }; locationAuthorizationRequest = Always; locationTemplate = ""; locationTimeout = 60; locationsOrderDirection = ASC; logLevel = 5; logMaxDays = 3; maxBatchSize = "-1"; maxDaysToPersist = 14; maxRecordsToPersist = "-1"; method = POST; minimumActivityRecognitionConfidence = 70; odometer = "177640.0414528051"; params = { }; pausesLocationUpdatesAutomatically = 1; persistMode = 2; preventSuspend = 0; schedule = ( ); schedulerEnabled = 0; showsBackgroundLocationIndicator = 1; startOnBoot = 1; stationaryRadius = 25; stopAfterElapsedMinutes = "-1"; stopDetectionDelay = 0; stopOnStationary = 0; stopOnTerminate = 0; stopTimeout = 1; trackingMode = 1; url = "https://tracker.transistorsoft.com/api/locations"; useSignificantChangesOnly = 0; } ℹ️-[GeofenceDAO init] CREATE TABLE IF NOT EXISTS geofences (id INTEGER PRIMARY KEY AUTOINCREMENT, identifier TEXT NOT NULL UNIQUE, latitude DOUBLE NOT NULL, sin_latitude DOUBLE NOT NULL, cos_latitude DOUBLE NOT NULL, longitude DOUBLE NOT NULL, sin_longitude DOUBLE NOT NULL, cos_longitude DOUBLE NOT NULL, radius DOUBLE NOT NULL, notifyOnEntry BOOLEAN NOT NULL DEFAULT 0, notifyOnExit BOOLEAN NOT NULL DEFAULT 0, notifyOnDwell BOOLEAN NOT NULL DEFAULT 0, loiteringDelay DOUBLE NOT NULL DEFAULT 0, extras TEXT, vertices TEXT) ℹ️-[GeofenceDAO init] CREATE index IF NOT EXISTS identifier ON geofences (identifier);CREATE index IF NOT EXISTS latitude ON geofences (latitude);CREATE index IF NOT EXISTS longitude ON geofences (longitude);CREATE index IF NOT EXISTS sin_latitude ON geofences (sin_latitude);CREATE index IF NOT EXISTS cos_latitude ON geofences (cos_latitude);CREATE index IF NOT EXISTS sin_longitude ON geofences (sin_longitude);CREATE index IF NOT EXISTS cos_longitude ON geofences (cos_longitude); πŸ”΅-[TSLocationManager locationManager:didChangeAuthorizationStatus:] status 3 πŸ”΅-[LocationManager locationManager:didChangeAuthorizationStatus:] 3 πŸ”΅-[PolygonGeofencingService locationManager:didChangeAuthorizationStatus:] 3 πŸ”΅-[LocationManager locationManager:didChangeAuthorizationStatus:] 3 πŸ”΅-[BackgroundTaskManager locationManager:didChangeAuthorizationStatus:] 3 πŸ”΅-[LocationManager locationManager:didChangeAuthorizationStatus:] 3 ℹ️+[LocationAuthorization run:onCancel:] status: 3 ℹ️-[TSLocationManager log:message:] [RNBackgroundGeolocation startObserving] ℹ️-[TSLocationManager on:success:failure:] location ℹ️-[TSLocationManager on:success:failure:] motionchange ℹ️-[TSLocationManager on:success:failure:] activitychange ℹ️-[TSLocationManager on:success:failure:] heartbeat ℹ️-[TSGeofenceManager onGeofence:] ℹ️-[TSGeofenceManager onGeofencesChange:] ℹ️-[TSLocationManager on:success:failure:] http ℹ️-[TSLocationManager on:success:failure:] providerchange ℹ️-[TSLocationManager on:success:failure:] schedule ℹ️-[TSLocationManager on:success:failure:] powersavechange ℹ️-[TSHttpService onConnectivityChange:] ℹ️-[TSLocationManager on:success:failure:] enabledchange ℹ️-[TSHttpService onAuthorization:] [TSBackgroundFetch scheduleBGAppRefresh] com.transistorsoft.fetch ℹ️-[TSConfig persist] πŸ”΅-[TSLocationManager ready] ℹ️-[TSLocationManager doStart:] trackingMode: 1 ℹ️-[TSLocationManager loadLastOdometerLocation] <+45.51903308,-73.60044343> +/- -1.00m (speed -1.00 mps / course -1.00) @ 2024-04-11, 9:16:09β€―AM Eastern Daylight Saving Time 🎾-[TSGeofenceManager start] [Geofencing] loadPolygon home 🎾-[PolygonGeofencingService startMonitoring:] home 🎾-[PolygonGeofencingService startUpdatingLocation:] 🎾-[SOMotionDetector startDetection] πŸ”΅-[TSLocationManager setPace:] 0 🎾-[TSLocationManager startUpdatingLocation] Location-services: ON '[location] - ', { odometer: 177640, age: 0, uuid: '3A2728D5-C47B-4566-978F-18BCC24DDB93', is_moving: false, sample: true, extras: {}, timestamp: '2024-04-11T13:16:09.075Z', coords: { altitude: 82.6, latitude: 45.51885986328125, heading: -1, altitude_accuracy: 15.8, heading_accuracy: -1, ellipsoidal_altitude: 51.2, accuracy: 7.3, speed_accuracy: -1, longitude: -73.60050296176078, speed: -1, floor: 2146959360 }, battery: { is_charging: false, level: -1 }, activity: { confidence: 100, type: 'unknown' } } βœ…-[SOMotionDetector startDetection]_block_invoke Enabled M7 MotionActivity updates ℹ️-[PolygonGeofencingService setLocation:] Already updating location πŸ“<+45.51944861,-73.60212178> +/- 4.72m (speed 1.75 mps / course 119.59) @ 2024-04-10, 3:01:46β€―PM Eastern Daylight Saving Time ╔═══════════════════════════════════════════════════════════ β•‘ -[TSGeofenceManager evaluateProximity:] Found 12 / 12 within 2000 m β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• ╔═══════════════════════════════════════════════════════════ β•‘ -[PolygonGeofencingService isInPolygon:] πŸ“ 45.518861, -73.600503, acy: 7.3m β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• ℹ️-[PolygonGeofencingService isInPolygon:] --> home: 100.0% ╔═══════════════════════════════════════════════════════════ β•‘ -[PolygonGeofencingService isInPolygon:] πŸ“ 45.518861, -73.600503, acy: 7.3m β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• ℹ️-[PolygonGeofencingService isInPolygon:] --> home: 100.0% πŸ“<+45.51886106,-73.60050296> +/- 7.32m (speed -1.00 mps / course -1.00) @ 2024-04-11, 9:16:09β€―AM Eastern Daylight Saving Time ╔═══════════════════════════════════════════════════════════ β•‘ -[TSLocationManager locationManager:didUpdateLocations:] Enabled: 1 | isMoving: 0 | df: -1.0m | age: 35 ms β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• βœ…-[TSLocationManager locationManager:didUpdateLocations:] Acquired motionchange position: <+45.51886106,-73.60050296> +/- 7.32m (speed -1.00 mps / course -1.00) @ 2024-04-11, 9:16:09β€―AM Eastern Daylight Saving Time ℹ️-[TSConfig persist] πŸ”΅-[TSConfig incrementOdometer:] 177659.7 πŸ”΅-[TSLocationManager startMonitoringStationaryRegion:radius:] Radius: 200 πŸ”΄-[TSLocationManager stopUpdatingLocation] πŸ”΅-[TSLocationManager calculateMedianLocationAccuracy:] Median location accuracy: 7.3 ℹ️-[PolygonGeofencingService setLocation:] Already updating location πŸ“<+45.51886106,-73.60050296> +/- 7.32m (speed -1.00 mps / course -1.00) @ 2024-04-11, 9:16:09β€―AM Eastern Daylight Saving Time ╔═══════════════════════════════════════════════════════════ β•‘ -[TSGeofenceManager evaluateProximity:] Found 12 / 12 within 2000 m β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• 🎾-[TSLocationManager startMonitoringSignificantLocationChanges] '[onMotionChange] - ', false, { activity: { type: 'unknown', confidence: 100 }, battery: { level: -1, is_charging: false }, extras: {}, coords: { floor: null, speed: -1, longitude: -73.60050296176078, speed_accuracy: -1, accuracy: 7.3, ellipsoidal_altitude: 51.2, heading_accuracy: -1, altitude_accuracy: 15.8, heading: -1, latitude: 45.51886105810753, altitude: 82.6 }, timestamp: '2024-04-11T13:16:09.081Z', is_moving: false, uuid: '4F07D1A3-A19C-485B-8812-BDEAA6EC394E', age: 39, event: 'motionchange', odometer: 177659.7 } ╔═══════════════════════════════════════════════════════════ β•‘ -[PolygonGeofencingService isInPolygon:] πŸ“ 45.518861, -73.600503, acy: 7.3m β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• ℹ️-[PolygonGeofencingService isInPolygon:] --> home: 100.0% πŸ”΄-[PolygonGeofencingService stopUpdatingLocation] ╔═══════════════════════════════════════════════════════════ β•‘ -[PolygonGeofencingService isInPolygon:] πŸ“ 45.518861, -73.600503, acy: 7.3m β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• ℹ️-[PolygonGeofencingService isInPolygon:] --> home: 100.0% βœ…-[LocationDAO unlock]_block_invoke UNLOCKED ALL RECORDS '[location] - ', { odometer: 177659.7, event: 'motionchange', age: 39, uuid: '4F07D1A3-A19C-485B-8812-BDEAA6EC394E', is_moving: false, timestamp: '2024-04-11T13:16:09.081Z', coords: { altitude: 82.6, latitude: 45.51886105810753, heading: -1, altitude_accuracy: 15.8, heading_accuracy: -1, ellipsoidal_altitude: 51.2, accuracy: 7.3, speed_accuracy: -1, longitude: -73.60050296176078, speed: -1, floor: null }, extras: {}, battery: { is_charging: false, level: -1 }, activity: { confidence: 100, type: 'unknown' } } βœ…-[TSLocationManager persistLocation:]_block_invoke INSERT: 4F07D1A3-A19C-485B-8812-BDEAA6EC394E ╔═══════════════════════════════════════════════════════════ β•‘ -[TSHttpService flush:] β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• βœ…-[BackgroundTaskManager createBackgroundTask] 2 βœ…-[TSHttpService schedulePost] LOCKED: 4F07D1A3-A19C-485B-8812-BDEAA6EC394E ℹ️+[LocationAuthorization run:onCancel:] status: 3 🎾-[TSLocationManager startMonitoringBackgroundFetch] BackgroundFetch: ON ```
christocracy commented 1 month ago

Plugin version: ^4.13.3

BTW, the latest version is 4.16.0 (see CHANGELOG)

christian-hess-94 commented 1 month ago

we have updated it, but it did not fix the issue.

Yes we noticed after that we are using another plugin to detect for location permissions (which it is detecting fine)

christocracy commented 1 month ago

Are you providing your logs here from the iOS Simulator?

christian-hess-94 commented 1 month ago

yes exactly. We are running it in the iPhone 15 (17.2) simulator

christocracy commented 1 month ago

You're aware of how you simulate location in the iOS Simulator with Features -> Location?

Screenshot 2024-04-11 at 9 37 03β€―AM
christian-hess-94 commented 1 month ago

yes we have a custom location set

christian-hess-94 commented 1 month ago

image it also shows up in the xCode logs, those are the lat lng values we have set

christocracy commented 1 month ago

yes we have a custom location set

I suggest you test with Features -> Location -> Apple.

christian-hess-94 commented 1 month ago

we will test it here one sec

christocracy commented 1 month ago

And if you've enabled Core Location [x] Allow Location Simulation in your Launch Config, disable it.

Screenshot 2024-04-11 at 9 48 08β€―AM
christian-hess-94 commented 1 month ago

will check here in a moment

christian-hess-94 commented 1 month ago

just verified, it is turned to YES but it has been set to YES for the past 4 years (git blame)

christocracy commented 1 month ago

Using GPX files is tricky. The GPX file can get "stuck" on a physical device requiring device restart if you don't do things correctly. You will also experience your phenomenon on other apps using location (eg: Google Maps, Apple Maps).

christian-hess-94 commented 1 month ago

got it i'll try with all of the above in a moment.

also i think it didn't become clear but this issue is affecting our app in production as well, running on iphone devices. From what we were able to gather, all iphone devices are presenting this issue, it's not an one-off that happened with only one or two of our users

christian-hess-94 commented 1 month ago

running the app with:

christocracy commented 1 month ago

The new Privacy Manifest has nothing at all to do with Location Services.

affecting our app in production as well,

Whatever you're experiencing is not due to the plugin. I'm testing every day for over 10 years. None of the other thousands of users are reporting anything like this.

christian-hess-94 commented 1 month ago

Yes after checking on the logs here I agree. We thought it was as the plugin is intrinsic to our app's function, as it controls the main feature that is provides (location tracking). I do appreciate you giving us pointers to check out what the issue could be.

Another question, before launching our MVP, we created multiple schemes (dev, stg) that are distributed to our internal testers prior to production release. Do you think it could be the reason for this issue? That somehow these new configurations / schemes could have de-configured the location tracking in the app in general, affecting prod as well?

christocracy commented 1 month ago

LocationError: 0 means the plugin asked the OS "Can I please have the current location?", and the OS replied "Sorry, I have no location to give: I don't know where I am".

Another question, before launching our MVP, we created multiple schemes (dev, stg)...Do you think it could be the reason for this issue?

I doubt that. Unless you've somehow managed to distribute a Debug build with Core Location [x] Allow Location Simulation.

christocracy commented 1 month ago

LocationError: 0

And like I said, when you receive this error in your app, you'll likely experience it on every other app on the device (eg: Google Maps, Apple Maps).

christian-hess-94 commented 1 month ago

doesn't that configuration also affect Release builds? as it's a global enabled/disabled config that affects all schemes and configs

christian-hess-94 commented 1 month ago

LocationError: 0

And like I said, when you receive this error in your app, you'll likely experience it on every other app on the device (eg: Google Maps, Apple Maps).

just verified by opening the Apple Maps app in the same simulator and on the iPhone device we use for testing (11 - 17.2), and it shows the location fine, marker on the map and all. further points that the issue is a misconfiguration on our part here

christocracy commented 1 month ago

After running my app with a GPX file on a physical device, I never trust my location. I always reboot my device (after re-launching with app with [ ] Allow Location Simulation disabled.

christian-hess-94 commented 1 month ago

got it i'll reboot it here

christian-hess-94 commented 1 month ago

image alright after doing all of that and relaunching the simulator, the location is being pinged again. Both with our manual trigger using the getCurrentPosition() call, and with the plugin's own internal HTTP flow.

however, the data is returning is_moving as false, even while the marker moves around. I will test in the device if this happen there as well, but could you know the reason for this? Again, this does not happen with android image

christocracy commented 1 month ago

I suggest you test in the simulator with Freeway Drive., not with your custom GPX file. The plugin determines the device is moving when it exits a 200 meter geofence around the last known location.

christian-hess-94 commented 1 month ago

ah yes i was using freeway drive, you can see the leftmost pings are all on the freeway near the Apple location.

Also this is_moving issue has happened before before we pushed the app into production a few months ago. it has always presented itself this way. It wasn't a blocker for release the app to prod, which is why we never pursued it before

christocracy commented 1 month ago

useSignificantChangesOnly: true,

is_moving is always false with that configuration.

christocracy commented 1 month ago

Suddenly getting a location unknown error

I believe your issue here is solved.

christian-hess-94 commented 1 month ago

Hello Chris, yes we have now verified that the app is working as intended! Spent the day doing a lot of debugging and driving around and was able to get a bunch of pings throught my route here. Also i got is_moving=true when setting useSignificantChange to off.

Thanks a lot for your help debugging this, I guess removing the Location Emulation flag did the trick!