Flutter-permission-handler: request() instantly resolves with permanently denied, even though the dialog to ask a user is being displayed

Created on 13 Jul 2021  路  16Comments  路  Source: Baseflow/flutter-permission-handler

馃悰 Bug Report

Expected behavior

When you request a permission, the returned future completes after the user has pressed something.

Actual behavior

request() instantly resolves with permanently denied, even though the correct dialog is being shown to users (and not resolved yet).

And yes, my setup was done correctly, if you press allow on the location always dialog you are correctly given the permission which is visible in the apps settings. However, for the state/flow of my app, having request resolve with permanently denied shows the incorrect UI.

Reproduction steps

Ask for location when in use, then location always right after.

Code Sample

  void processAskForLocationPermission() async {
    final whenInUseStatus = await locationWhenInUsePermission.request();
    print("whenInUseStatus: $whenInUseStatus");

    if (whenInUseStatus == PermissionStatus.permanentlyDenied || whenInUseStatus == PermissionStatus.denied) {
      return;
    }

    // this future completes instantly, even though the dialog is still visible to the user
    final alwaysStatus = await locationAlwaysPermission.request(); 
   // this prints "always: PermissionStatus.permanentlyDenied" immediately after the above line finishes
    print("always: $alwaysStatus");
  }

Configuration

Version: permission_handler: ^8.1.2

(also tested 6.0.1 and found the same issue)

Platform:
iOS

Most helpful comment

i only found this issue in iOS. Android working fine.
i tested version 8.1.2 and 8.1.1, both not working. i'm rolled back to 7.2.0 and iOS is now working.

All 16 comments

i only found this issue in iOS. Android working fine.
i tested version 8.1.2 and 8.1.1, both not working. i'm rolled back to 7.2.0 and iOS is now working.

As I wrote in the linked issue, for me issue was this:

8.0.0: This release contains the following breaking changes:

Starting from this version the permissions on iOS are disabled by default. To enable a permission, specify the correct GCC_PREPROCESSOR_DEFINITIONS in the ios/Podfile file. For an example check out the Podfile of the example application.

I had to update my pod file to write now only permissions that I want with 1, now everything works for me.

I am absolutely positive I have done the iOS setup correctly. I have even done a release to the apple store since upgrading to 8.1.2 and flutter 2 null safety. If this was done incorrectly, the release would have been blocked from missing permission strings and such.

      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        'PERMISSION_CAMERA=1',
        'PERMISSION_PHOTOS=1',
        'PERMISSION_LOCATION=1',
        'PERMISSION_NOTIFICATIONS=1',
        '

i only found this issue in iOS. Android working fine.
i tested version 8.1.2 and 8.1.1, both not working. i'm rolled back to 7.2.0 and iOS is now working.

This one solved the problem for me...

I am absolutely positive I have done the iOS setup correctly. I have even done a release to the apple store since upgrading to 8.1.2 and flutter 2 null safety. If this was done incorrectly, the release would have been blocked from missing permission strings and such.

      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        'PERMISSION_CAMERA=1',
        'PERMISSION_PHOTOS=1',
        'PERMISSION_LOCATION=1',
        'PERMISSION_NOTIFICATIONS=1',
        '

i found out, 8.1.2 worked with the described Podfile changes, described in the plugin documentation. but if i have a user, who disable a permission in the app settings in the system UI, than Permission.somePermission.request() gives always permanentlyDenied.

Hi @MilesAdamson, I worked on this issue today and made a fix where the user now can ask for the locationAlways permission. I found out today that asking for the locationAlways permission will not work, most likely because of some bug using the Apple's CLLocationManager's requestAlwaysAuthorization() method. The permission can be requested as how it will be stated in the updated documentation saying the following:

The `locationAlways` permission can not be requested directly, the user has to request the `locationWhenInUse` permission first.
Accepting this permission by clicking on the 'Allow While Using App' gives the user the possibility to request the `locationAlways` permission.
This will then bring up another permission popup asking you to `Keep Only While Using` or to `Change To Always Allow`.

The PR will be reviewed and merged most likely in the next few days. Let me know if this solved your problem so I can close the issue.

the user has to request the locationWhenInUse permission first.

I did, look at my code sample. I don't think your PR will address the issue but I'll check out your branch today and confirm

Misclick, sorry

Let me know if this solved your problem so I can close the issue.

It did not. What happened was this:

  • Ask for location when in use

    • Press allow when using app

    • Location when in use request returns PermissionStatus.granted

  • Ask for location always right after

    • Press allow always

    • Location always request incorrectly returns PermissionStatus.denied



      • My UI still shows a button to ask for the permission since it thinks it's denied



    • Call await Permission.locationAlways.request() again

    • Returns PermissionStatus.granted (no dialog is shown on screen)

There is one change with how it used to behave, Before, await Permission.locationAlways.request() would show the "change to always dialog" and the future would resolve before anything happened with the dialog (as per the title of the issue). With your change, it does properly await the result of the dialog, but it incorrectly returns denied after I have pressed accept

Hi @MilesAdamson, thank you for pointing out the bug with a clear description of the problem. We were able to pinpoint the bug and there is currently a PR for the bug fix that can be reviewed and will be merged soon. The problem was that when asking the WhenInUse permission the LocationManager listens to permissions changes being made, and did not remove this listener when asking for the locationAlways permission. So when asking for the locationAlways another listener is created, and this made it possible for the plugin to sometimes return Granted and sometimes returning Denied (depends on which listener 'reacted'). I debugged and tested it in both the example app and a quick test app (standard flutter counter project with your code sample). It shows the behavior that it should do now, can you let me know if it does the same for you so I can close this issue? Thanks again for bringing this to our attention!

@JDDV great thank you, appears to be all working now

@JDDV Unfortunatelly I'm still getting the same error in version 8.1.4. Tested using iOS Simulator.

OBS: Please, ignore, I fixed it by updating the Podfile.

Please check on microphone permission also, some how its return wrong permission on IOS, its granted but the result is "Permanently Denied"

for location it is still returning permanently denied and it does not request for the permission as well
platform: IOS
version: 8.1.4

@BasitCh have you updated the podfile? Since version ^8.0.0 the podfile should look different than it did before as stated in the setup section of the documentation.

your podfile should say something like:

## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
        'PERMISSION_LOCATION=1',

Can you also try to run a flutter clean followed by a flutter pub get and pod install to make sure no caching issues will happen?

also make sure you read the documentation stated when using locationAlways. The user should first ask for locationWhenInUse and then the you can request the locationAlways permission.

Let me know this solved your problem!

@MilesAdamson, I would like to point out to you that there still was a bug in version ^8.1.4 which is fixed now. the new version is ^8.1.4+1 which should fix all the problems.

Was this page helpful?
0 / 5 - 0 ratings