flutter-permission-handler icon indicating copy to clipboard operation
flutter-permission-handler copied to clipboard

[Bug]: Permission not granted in first time, We need to rebuild the app again to see ther permission change

Open Zahid046 opened this issue 1 year ago • 14 comments

Please check the following before submitting a new issue.

Please select affected platform(s)

  • [ ] Android
  • [X] iOS
  • [ ] Windows

Steps to reproduce

First add the first 2 line before the runApp function in main()

then give permission and log the output, it says permissionStatus.granted

but when i call on

await Permission.calendarFullAccess.status

[ you can uncomment the commented part and check]

is says permissionStatus.denied

But when i close out the app and rebuild it on xcode or vscode again, then it says

permissionStatus.granted

it takes new rebuild to configure the permission, which is not good

Expected results

it should show the granted permission for all state after the permission is granted by the user. Not after the rebuild of the app again

Actual results

It says permission denied and

INVOKE_CHANNEL_METHOD_ERROR: PlatformException(401, The user has not allowed this application to modify their calendar(s), null, null)

for the first time and then it fixes itself after rebuilding the app again

Code sample

Code sample
  await Permission.calendarWriteOnly.request();
  await Permission.calendarFullAccess.request();
  
  
    static Future<PermissionStatus> _calendarPermissions() async {
    Map<Permission, PermissionStatus> permissionStatus = await [Permission.calendarWriteOnly].request();
    log("--- : " + permissionStatus.toString());
    return permissionStatus[Permission.calendarWriteOnly] ?? PermissionStatus.denied;

    // PermissionStatus permission = await Permission.calendarWriteOnly.status;
    // if (!permission.isGranted) {
    //   log(permission.toString());
    //   Map<Permission, PermissionStatus> permissionStatus = await [Permission.calendarWriteOnly].request();
    //   log("--- : " + permissionStatus.toString());
    //   return permissionStatus[Permission.calendarWriteOnly] ?? PermissionStatus.denied;
    // } else {
    //   return permission;
    // }
  }

  static Future<PermissionStatus> _calendarPermissions2() async {
    Map<Permission, PermissionStatus> permissionStatus = await [Permission.calendarFullAccess].request();
    log("--- : " + permissionStatus.toString());
    return permissionStatus[Permission.calendarFullAccess] ?? PermissionStatus.denied;

    // PermissionStatus permission = await Permission.calendarFullAccess.status;
    // if (!permission.isGranted) {
    //   log(permission.toString());
    //   Map<Permission, PermissionStatus> permissionStatus = await [Permission.calendarFullAccess].request();
    //   log("--- : " + permissionStatus.toString());
    //   return permissionStatus[Permission.calendarFullAccess] ?? PermissionStatus.denied;
    // } else {
    //   return permission;
    // }
  }

  Future<bool> calendarPermissionsGranted() async {
    PermissionStatus calendarPermissionsStatus = await _calendarPermissions();
    log("break");
    PermissionStatus calendarPermissionsStatus2 = await _calendarPermissions2();
    // if (calendarPermissionsStatus2.isGranted) {
    if (calendarPermissionsStatus.isGranted && calendarPermissionsStatus2.isGranted) {
      log("yes");
      return true;
    } else {
      log("no");
      return false;
    }
  }

Screenshots or video

Screenshots or video demonstration

[Upload media here]

Version

11.1.0

Flutter Doctor output

Doctor output
flutter doctor -v
[✓] Flutter (Channel stable, 3.16.0, on macOS 14.0 23A344 darwin-x64, locale en-JP)
    • Flutter version 3.16.0 on channel stable at /Users/emongenie/Downloads/Apps/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision db7ef5bf9f (7 days ago), 2023-11-15 11:25:44 -0800
    • Engine revision 74d16627b9
    • Dart version 3.2.0
    • DevTools version 2.28.2

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/emongenie/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15A507
    • CocoaPods version 1.14.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)

[✓] VS Code (version 1.84.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.76.0

[✓] Connected device (3 available)
    • iPhone 15 Pro Max (mobile) • 744BEB5C-7838-4731-8C65-3FFF26E3F994 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-17-0 (simulator)
    • macOS (desktop)            • macos                                • darwin-x64     • macOS 14.0 23A344 darwin-x64
    • Chrome (web)               • chrome                               • web-javascript • Google Chrome 119.0.6045.159
    ! Error: Browsing on the local area network for iPhone. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)

[✓] Network resources
    • All expected network resources are available.

• No issues found!

Zahid046 avatar Nov 22 '23 11:11 Zahid046

I'm facing the same issue with Android 10.

Permission.storage.request();

The first request results in an error: W/permissions_handler(22142): onRequestPermissionsResult is called without results. This is probably caused by interfering request codes. If you see this error, please file an issue in flutter-permission-handler, including a list of plugins used by this application: https://github.com/Baseflow/flutter-permission-handler/issues

After restarting the app, it works with the permission granted.

tiendangminh avatar Nov 23 '23 04:11 tiendangminh

Hi @Zahid046, thank you for bringing this to our attention!

Some initial questions that pop into my head:

  • What iOS version are you using?
  • What happens when you only request Permission.calendarFullAccess?

JeroenWeener avatar Nov 23 '23 15:11 JeroenWeener

  1. I am using ios 17 on iphone 15 pro max simulator and also in iphone SE3 and iphone 11 which all have ios 17 available to them

  2. If permission.calendarFullAccess is called and the permission is given then

INVOKE_CHANNEL_METHOD_ERROR: PlatformException(401, The user has not allowed this application to modify their calendar(s), null, null) thiss error shows up

then after closing the app completely and rebuilding again it shows that permission is granted and it gives access to the calendar.

thats where i am stuck now. as it is not a very good approach to gain access on calendar in user level

@JeroenWeener

Zahid046 avatar Nov 23 '23 15:11 Zahid046

We faced a similar issue in iOS 17 after updating permission_hanlder to 11.1.0.

We added both NSCalendarsUsageDescription & NSCalendarsFullAccessUsageDescription in the Info.plist, and PERMISSION_EVENTS_FULL_ACCESS=1 & PERMISSION_EVENTS=1 in the Podfile.

Then we called permission.calendarFullAccess.request() and it prompted the user to give full access (and it shows in the settings that a full access calendar permission had been given), but it would not work unless the user changed it manually (from the setting) to be "None/ Write Only" then to "Full Access".

MrOsamah avatar Nov 28 '23 06:11 MrOsamah

@MrOsamah its actually same when you go to settings and change it manually you have to restart the app. Thats what i am also facing. But seems like it is not concerning the author of the package to fix it right now, But lets see

Zahid046 avatar Nov 28 '23 07:11 Zahid046

@mvanbeusekom @JeroenWeener Thanks for your hard work guys, would you consider making this issue a higher priority (or let us know what you think about it), I think it happens for all iOS 17 devices.

MrOsamah avatar Dec 06 '23 12:12 MrOsamah

@JeroenWeener any update?

Zahid046 avatar Dec 10 '23 12:12 Zahid046

This is also a big problem for me. Because access is granted only after a complete restart of the program ( And this solution https://github.com/Baseflow/flutter-permission-handler/issues/1108#issuecomment-1826979829 does not help

mev007 avatar Jan 05 '24 02:01 mev007

Facing a similar issue as well @JeroenWeener

Using IOS 17.1.2 Iphone 13 Pro

But on my end await Permission.calendarFullAccess.request(); doesn't event request for calendar permission

Already added this in my Podfile

   ## dart: [PermissionGroup.calendarWriteOnly, PermissionGroup.calendar (until iOS 16)]
       'PERMISSION_EVENTS=1',

   ## dart: [PermissionGroup.calendarFullAccess, PermissionGroup.calendar (from iOS 17)]
       'PERMISSION_EVENTS_FULL_ACCESS=1',

   ## dart: PermissionGroup.reminders
       'PERMISSION_REMINDERS=1',

And this on my Info.plist

<!-- Permission options for the `calendar` group -->
<key>NSCalendarsUsageDescription</key>
<string>Allow permission in order to process your loan application</string>
<key>NSCalendarsFullAccessUsageDescription</key>
<string>Calendar full access</string>
<key>NSRemindersFullAccessUsageDescription</key>
<string>Reminders full access</string>

Code

 Future<void> _requestIOSPermissions() async {
    try {
      await Permission.calendarFullAccess.request();
      final calendarStatus = await Permission.calendarFullAccess.status;
      //log calendarStatus here is always denied
    } catch (e) {
      print(e);
    }
  }

Let me know if you need anything else would be glad to help

ianvillamia avatar Jan 09 '24 05:01 ianvillamia

Thanks for the package! any news on this issue or a temporary workaround ?

einatguri avatar Jan 22 '24 12:01 einatguri

It seems that device_calendar has a fix on their develop branch (but needs full access unfortunately), check builttoroam/device_calendar/#490.

MrOsamah avatar Jan 22 '24 17:01 MrOsamah

It seems that device_calendar has a fix on their develop branch (but needs full access unfortunately), check builttoroam/device_calendar/#490.

It doesn't change the problematic behavior. I still need to restart the app after asking for permissions before i can move on to the feature functionality.

einatguri avatar Jan 23 '24 08:01 einatguri

It doesn't change the problematic behavior. I still need to restart the app after asking for permissions before i can move on to the feature functionality.

@einatguri @mulvad Sorry I didn't elaborate.

We used the device_dalendar's methods DeviceCalendarPlugin.requestPermissions and DeviceCalendarPlugin.hasPermission, maybe it will help you in your case.

MrOsamah avatar Jan 23 '24 10:01 MrOsamah

It doesn't change the problematic behavior. I still need to restart the app after asking for permissions before i can move on to the feature functionality.

@einatguri @mulvad Sorry I didn't elaborate.

We used the device_dalendar's methods DeviceCalendarPlugin.requestPermissions and DeviceCalendarPlugin.hasPermission, maybe it will help you in your case.

it seems to be working for this specific scenario. Thanks!

einatguri avatar Jan 25 '24 07:01 einatguri

Hello All,

Any updates?

M7md-Abaza avatar Feb 26 '24 13:02 M7md-Abaza

Hello all,

Unfortunately we are unable to reproduce this issue. To reproduce the issue I have creates a quick test application taking the following steps:

  1. Create new Flutter application: flutter create --platforms=ios issue_1235.
  2. Change into the project directory: cd issue_1235.
  3. Add a dependency on the latest permission_handler plugin: flutter pub add permission_handler.
  4. Add required configuration to the ios/Podfile (see code below).
  5. Add required configuration to the ios/Runner/Info.plist (see code below).
  6. Update the lib/main.dart to request full access to the Calendar (see code below).
  7. Run the application and hit the floating action button to request permission, the method returns "granted" right away.

Code files I updated:

ios/Podfile
# Uncomment this line to define a global platform for your project
# platform :ios, '12.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
  'Debug' => :debug,
  'Profile' => :release,
  'Release' => :release,
}

def flutter_root
  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
  unless File.exist?(generated_xcode_build_settings_path)
    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
  end

  File.foreach(generated_xcode_build_settings_path) do |line|
    matches = line.match(/FLUTTER_ROOT\=(.*)/)
    return matches[1].strip if matches
  end
  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
  target 'RunnerTests' do
    inherit! :search_paths
  end
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)

    target.build_configurations.each do |config|
      # You can remove unused permissions here
      # for more information: https://github.com/BaseflowIT/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
      # e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: PermissionGroup.calendar
        'PERMISSION_EVENTS=1',
        
        ## dart: PermissionGroup.calendarFullAccess
        'PERMISSION_EVENTS_FULL_ACCESS=1',
      ]

    end

  end
end
ios/Runner/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>$(DEVELOPMENT_LANGUAGE)</string>
	<key>CFBundleDisplayName</key>
	<string>Issue 1235</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>issue_1235</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>$(FLUTTER_BUILD_NAME)</string>
	<key>CFBundleSignature</key>
	<string>????</string>
	<key>CFBundleVersion</key>
	<string>$(FLUTTER_BUILD_NUMBER)</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>UILaunchStoryboardName</key>
	<string>LaunchScreen</string>
	<key>UIMainStoryboardFile</key>
	<string>Main</string>
	<key>UISupportedInterfaceOrientations</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
	<key>UISupportedInterfaceOrientations~ipad</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationPortraitUpsideDown</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
	<key>CADisableMinimumFrameDurationOnPhone</key>
	<true/>
	<key>UIApplicationSupportsIndirectInputEvents</key>
	<true/>

	<!-- Permission options for the `calendar` group -->
    <key>NSCalendarsUsageDescription</key>
    <string>Calendars</string>
    <key>NSCalendarsFullAccessUsageDescription</key>
    <string>Calendar full access</string>
</dict>
</plist>
pubspec.yaml
name: issue_1235
description: "A new Flutter project."
publish_to: 'none'
version: 1.0.0+1

environment:
  sdk: '>=3.3.1 <4.0.0'

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.6
  permission_handler: ^11.3.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.0

flutter:
  uses-material-design: true

lib/main.dart
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _permissionStatus = PermissionStatus.denied.name;

  Future<void> _requestCalendarPermission() async {
    final PermissionStatus permissionStatus =
        await Permission.calendarFullAccess.request();

    setState(() {
      _permissionStatus = permissionStatus.name;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'Full access calendar status:',
            ),
            Text(
              '$_permissionStatus',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _requestCalendarPermission,
        tooltip: 'Request calendar permission',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

Here is the output of flutter doctor -v from my environment:

[✓] Flutter (Channel stable, 3.19.3, on macOS 14.3.1 23D60 darwin-arm64, locale en-US)
    • Flutter version 3.19.3 on channel stable at /Users/maurits/development/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ba39319843 (12 days ago), 2024-03-07 15:22:21 -0600
    • Engine revision 2e4ba9c6fb
    • Dart version 3.3.1
    • DevTools version 2.31.1

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/maurits/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.2)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15C500b
    • CocoaPods version 1.14.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2023.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874)

[✓] VS Code (version 1.87.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.84.0

[✓] Connected device (4 available)
    • Pixel 7a (mobile)                      • 31071JEHN18081            • android-arm64  • Android 14 (API 34)
    • Maurits van Beusekom’s iPhone (mobile) • 00008101-000D543E1A40001E • ios            • iOS 17.3.1 21D61
    • macOS (desktop)                        • macos                     • darwin-arm64   • macOS 14.3.1 23D60 darwin-arm64
    • Chrome (web)                           • chrome                    • web-javascript • Google Chrome 122.0.6261.129

[✓] Network resources
    • All expected network resources are available.

• No issues found!

Reading the original question carefully, I noticed the sentence "First add the first 2 line before the runApp function in main()". It is important to make sure that permissions are only requested when the Flutter engine is fully loaded. If you want to request permission before the runApp call make sure that you first call WidgetsFlutterBinding.ensureInitialized(); before calling into the permission_hanlder. More information about this can be found here.

If anyone is still experiencing this issue, please provide an example similar to mine demonstrating the problem.

mvanbeusekom avatar Mar 19 '24 09:03 mvanbeusekom

Without additional information, we are unfortunately not able to resolve this issue. Therefore, we reluctantly closed this issue for now. If you run into this issue later, feel free to file a new issue with a reference to this issue. Add a description of detailed steps to reproduce, expected and current behaviour, logs and the output of 'flutter doctor -v'. Thanks for your contribution.

github-actions[bot] avatar Apr 02 '24 10:04 github-actions[bot]

I still encountered this issue yesterday where I got [(401, That account does not allow calendars to be added or removed., null, null)] after granting full access to calendars and then trying to retrieve calendars using:

await _deviceCalendarPlugin.retrieveCalendars()

I'm running iOS 17.2 on the stimulator.

Where I differ from the OP is instead of restarting my app, I noticed that if when I navigate to another screen that also uses this package and then navigate back to the screen where I encountered this issue, then my calendars would get retrieved without error.

After some trial and error, I realized that before await _deviceCalendarPlugin.retrieveCalendars() I need to first do a permission check by first running:

await _deviceCalendarPlugin.requestPermissions();

Before I would only run await _deviceCalendarPlugin.hasPermissions() before trying to retrieve calendars with await _deviceCalendarPlugin.retrieveCalendars().

Hope this helps.

stephenjen avatar Jun 26 '24 04:06 stephenjen