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

Prevent locationAuthorizationAlert to be shown on app start

Open UnderTheMoonspell opened this issue 1 year ago • 14 comments

Your Environment

  • Plugin version: 4.14.3
  • Platform: iOS
  • OS version: 17.2
  • Device manufacturer / model: Simulator
  • React Native version (react-native -v): 0.71.4
  • Plugin config
{
      url:*****,
      headers: {
        ...getGlobalDefaultHeaders(),
      },
      autoSync: true,
      reset: true,
      geofenceModeHighAccuracy: true, // <-- consumes more power; default is false.
      debug: __DEV__,
      logLevel: __DEV__
        ? BackgroundGeolocation.LOG_LEVEL_VERBOSE
        : BackgroundGeolocation.LOG_LEVEL_OFF,
      stopOnTerminate: false,
      startOnBoot: true,
      desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH,
      disableLocationAuthorizationAlert: false, // TODO This controls if the modal shows up on start
      locationAuthorizationRequest: 'Always',
      disableMotionActivityUpdates: true,
      backgroundPermissionRationale: {
        title: "Allow {applicationName} to access to this device's location in the background?",
        message:
          'In order to track your activity in the background, please enable {backgroundPermissionOptionLabel} location permission',
        positiveAction: 'Change to {backgroundPermissionOptionLabel}',
        negativeAction: 'Cancel',
      },
      locationAuthorizationAlert: {
        titleWhenNotEnabled: 'Hey! location services are not enabled',
        titleWhenOff: 'Hey! location services are off',
        instructions: "You must enable 'Always' in location services",
        cancelButton: 'Cancel',
        settingsButton: 'Settings',
      },
}

Expected Behavior

I would expect the locationAuthorizationAlert to not show on subsequent boots until we call .requestPermission().

Actual Behavior

On a subsequent load of the app, the locationAuthorizationAlert is being shown just by calling the .ready() method

https://github.com/transistorsoft/react-native-background-geolocation/assets/10156878/435e3085-db5f-4545-8e26-979aa2c4c232

Steps to Reproduce

  1. call ready on every boot
  2. call startGeofences on setup (only one time)
  3. close the app
  4. load the app

Context

Debug logs

Logs
PASTE_YOUR_LOGS_HERE

UnderTheMoonspell avatar Jan 12 '24 15:01 UnderTheMoonspell

disableLocationAuthorizationAlert: false,

If you don't want to see the alert, set true.

If the plugin is in Start.enabled, calling .ready(config) on app launch will cause the plugin to evaluate permissions and show alerts as necessary.

Also see API docs Config.locationAuthorizationRequest and read about the option Any.

christocracy avatar Jan 12 '24 15:01 christocracy

But if I set it to true then i cannot show it again, and It would be helpful to show it again instead of developing a new alert.

I may be able to work around it with locationAuthorizationRequest, but it seems to be a weird workaround for something that could be a config option.

Il give it a try, thanks for the help!

UnderTheMoonspell avatar Jan 12 '24 15:01 UnderTheMoonspell

This alert has existed for over 8 years like this for thousands of users.

You are free to modify the Config (eg disableAuthorizationAlert) at any time in the future (after .ready(config) has been called) using .setConfig(new config).

christocracy avatar Jan 12 '24 16:01 christocracy

You're also free to listen to the onProviderChange event to be notified of the current permission state event and take control of your own alerts.

christocracy avatar Jan 12 '24 16:01 christocracy

First, I really want to thank you for writing such a nice and extensive plugin with very detailed documentation to boot and also for being so helpful on replying to the devlopers, but the fact it has existed like that for thousands of users, doesn't mean it cannot be improved, and im just suggesting an improvement.

I have tried to use setConfig to change disableAuthorizationAlert from true to false, but it doesn't trigger the popup immediately (only if I click it two times - check the video). It will also show the next time the user loads the app, which ends up being the thing im trying to avoid (i tried using setConfig to revert it on the useEffect cleanup function but it didnt work).

https://github.com/transistorsoft/react-native-background-geolocation/assets/10156878/9ef68b54-03ea-4fbf-86da-b53c5debec54

UnderTheMoonspell avatar Jan 12 '24 17:01 UnderTheMoonspell

but it doesn't trigger the popup

After modifying the Config, you would have to invoke a method that would cause the plugin to have to request permission. Eg:

  • .getCurrentPosition()
  • .requestPermission()

christocracy avatar Jan 12 '24 17:01 christocracy

but the fact it has existed like that for thousands of users, doesn't mean it cannot be improved

I don't believe there needs to be any improvement in this case. I believe the plugin can already do what you need.

christocracy avatar Jan 12 '24 17:01 christocracy

@christocracy I almost got the behavior I wanted, but there is still something that doesn't make sense. In the first run, I always need to call requestPermission() twice to trigger the popup, but in subsequent runs it always works as intended

This is the method that the top button calls directly:

const requestUserAuthorization = async () => {
    try {
      await BackgroundGeolocation.setConfig({ disableLocationAuthorizationAlert: false });
      const status = await BackgroundGeolocation.requestPermission();
      setAuthorizationStatus(status);
    } catch (err) {
      setAuthorizationStatus(err);
    } finally {
      await BackgroundGeolocation.setConfig({ disableLocationAuthorizationAlert: true });
    }
  };

https://github.com/transistorsoft/react-native-background-geolocation/assets/10156878/545b535c-56e5-4c80-86bd-fbe5e10b6c8b

UnderTheMoonspell avatar Jan 15 '24 10:01 UnderTheMoonspell

Are you observing what's happening in the logs? The first thing to do, before making a sceeen recording, is to look what the logs say.

christocracy avatar Jan 15 '24 13:01 christocracy

These are the logs for the first run:

2024-01-15 17:26:56.167 ℹ️-[TSLocationManager log:message:] [useGeolocation] getState - Enabled

2024-01-15 17:26:56.167 ℹ️-[TSLocationManager log:message:] [useGeolocation] [getProviderState]

2024-01-15 17:26:57.676 ℹ️-[TSLog destroy] SUCCESS

2024-01-15 17:27:00.526 ℹ️-[TSLocationManager log:message:] [useGeolocation] Start tracking geofences

2024-01-15 17:27:00.526 ╔═══════════════════════════════════════════════════════════ ║ -[TSLocationManager startGeofences] ╚═══════════════════════════════════════════════════════════

2024-01-15 17:27:00.526 ℹ️-[TSLocationManager doStart:] trackingMode: 0

2024-01-15 17:27:00.526 ℹ️-[TSConfig persist]

2024-01-15 17:27:00.543 ℹ️-[TSConfig persist]

2024-01-15 17:27:00.546 ℹ️-[TSLocationManager clearLastOdometerLocation]

2024-01-15 17:27:00.547 🎾-[TSGeofenceManager start]

2024-01-15 17:27:00.548 🔵-[TSLocationManager setPace:] 0

2024-01-15 17:27:00.562 🎾-[TSLocationManager startUpdatingLocation] Location-services: ON

2024-01-15 17:27:00.563 ╔═══════════════════════════════════════════════════════════ ║ -[TSHttpService flush:] ╚═══════════════════════════════════════════════════════════

2024-01-15 17:27:00.564 ✅-[LocationDAO unlock]_block_invoke UNLOCKED ALL RECORDS

2024-01-15 17:27:00.564 ╔═══════════════════════════════════════════════════════════ ║ -[TSHttpService finish:error:] Success: 1 ╚═══════════════════════════════════════════════════════════

2024-01-15 17:27:00.580 ℹ️+[LocationAuthorization run:onCancel:] status: 0

2024-01-15 17:27:00.580 🔵+[LocationAuthorization run:onCancel:] Request: requestAlwaysAuthorization

2024-01-15 17:27:00.581 🎾-[TSLocationManager startMonitoringBackgroundFetch] BackgroundFetch: ON

2024-01-15 17:27:00.629 ℹ️-[TSLocationManager startMonitoringBackgroundFetch]_block_invoke Configured BackgroundFetch

2024-01-15 17:27:02.144 🔵-[BackgroundTaskManager locationManager:didChangeAuthorizationStatus:] 2

2024-01-15 17:27:02.145 🔵-[LocationManager locationManager:didChangeAuthorizationStatus:] 2

2024-01-15 17:27:02.145 🔵-[LocationManager locationManager:didChangeAuthorizationStatus:] 2

2024-01-15 17:27:02.145 🔵-[LocationManager locationManager:didChangeAuthorizationStatus:] 2

2024-01-15 17:27:02.146 🔵-[PolygonGeofencingService locationManager:didChangeAuthorizationStatus:] 2

2024-01-15 17:27:02.146 ⚠️-[TSLocationManager locationManager:didFailWithError:] Error Domain=kCLErrorDomain Code=1 "(null)"

2024-01-15 17:27:02.161 ℹ️-[TSConfig persist]

2024-01-15 17:27:02.164 🔵-[TSLocationManager locationManager:didChangeAuthorizationStatus:] status 2

2024-01-15 17:27:02.185 ℹ️-[TSLocationManager log:message:] [useGeolocation] [OnProviderChange]

2024-01-15 17:27:02.186 ℹ️-[TSLocationManager log:message:] [useGeolocation] [OnProviderChange]

2024-01-15 17:27:02.198 ℹ️+[LocationAuthorization run:onCancel:] status: 2

2024-01-15 17:27:02.574 ⚠️-[TSLocationManager locationManager:didFailWithError:] Error Domain=kCLErrorDomain Code=1 "(null)"

2024-01-15 17:27:04.704 ℹ️-[TSLocationManager log:message:] [useGeolocation] requestUserAuthorization start

2024-01-15 17:27:04.704 ℹ️-[TSConfig persist]

2024-01-15 17:27:04.725 ℹ️+[LocationAuthorization run:onCancel:] status: 2

2024-01-15 17:27:04.728 ℹ️-[TSConfig persist]

2024-01-15 17:27:04.728 ℹ️-[TSLocationManager log:message:] [useGeolocation] requestUserAuthorization error

I then compared with the logs of the second call to the requestPermission method, but I am unable to find something that can help me:

2024-01-15 17:31:04.634 ℹ️-[TSLog destroy] SUCCESS

2024-01-15 17:31:10.146 ℹ️-[TSDBLogger db_save] Log committed

2024-01-15 17:31:10.234 ℹ️-[TSLocationManager log:message:] [useGeolocation] requestUserAuthorization start

2024-01-15 17:31:10.235 ℹ️-[TSConfig persist]

2024-01-15 17:31:10.244 ℹ️+[LocationAuthorization run:onCancel:] status: 2

2024-01-15 17:31:10.249 ℹ️-[TSLocationManager log:message:] [useGeolocation] requestUserAuthorization error

UnderTheMoonspell avatar Jan 15 '24 16:01 UnderTheMoonspell

2024-01-15 17:27:02.146 ⚠️-[TSLocationManager locationManager:didFailWithError:] Error Domain=kCLErrorDomain Code=1 "(null)"

See API docs LocationError. Code=1 means "Location Permission Denied".

2024-01-15 17:27:02.145 🔵-[LocationManager locationManager:didChangeAuthorizationStatus:] 2

See API docs AuthorizationStatus. 2 means AUTHORIZATION_STATUS_DENIED.

Why are you denying location authorization to your own app?

christocracy avatar Jan 15 '24 17:01 christocracy

I want to code for the scenario where the user will click "Don't Allow", so that then we show some disclaimer that it cant use some features and needs to give "Always" permissions. We would also present a button to the user to then call requestPermission(). I am just trying to avoid having to click two times on the first app boot. Everything else seems to be working as I intended.

UnderTheMoonspell avatar Jan 15 '24 17:01 UnderTheMoonspell

See api docs onProviderChange to learn about the current state of permissions.

Also method .getProviderState

christocracy avatar Jan 15 '24 17:01 christocracy

Ok I think I got it working, the trick was to set the reset property to false. If anyone needs to do something similar:

Basically this is the config:

image

And the method to trigger the permissions popup has to do something like this:

image

I think as a potential improvement, this could be a config property like disableLocationAuthorizationAlertOnStartup or something similar.

Thanks for the help

UnderTheMoonspell avatar Jan 16 '24 10:01 UnderTheMoonspell