How to find permanentlyDenied status using this package?
I just tested to get the permission like this (as described in the example):
final FlutterLocalNotificationsPlugin _plugin =
FlutterLocalNotificationsPlugin();
final ios = _plugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin
>();
NotificationsEnabledOptions? result = await ios?.checkPermissions();
Since all returned where false I tried to request permission:
final ios = _plugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>();
await ios?.requestPermissions(alert: true, badge: true, sound: true);
Popup requesting notification is is shown, as expected. BUT if the user press not allow the requestPermissions() will not show an notification request dialog again.
After reading about this, there is a "permanentDenied" status. Se enum from permission_handler package: https://pub.dev/documentation/permission_handler/latest/permission_handler/PermissionStatus.html
Only supported on iOS (iOS14+) and Android (Android 14+)
permanentlyDenied → const PermissionStatus Permission to the requested feature is permanently denied, the permission dialog will not be shown when requesting this permission. The user may still change the permission status in the settings.
On Android: Android 11+ (API 30+): whether the user denied the permission for a second time. Below Android 11 (API 30): whether the user denied access to the requested feature and selected to never again show a request.
On iOS: If the user has denied access to the requested feature.
Is it possible to get this status in flutter_local_notifications? If not, may I suggest to implement it, since you want to guide your user to settings screen to handle such case.
Hi, I'm in the process of rewriting our documentation. This is one area I was struggling with actually. On the one hand, you're right that this plugin could be a bit more out of the box. On the other hand, there is a great plugin permission_handler that can request permissions, check permissions status, and even take the user to the app page in the settings app to manually make changes.
The way I see it there are a few options, including:
- Remove all permissions code from this plugin, refer users to permission handler instead. Pros: less code maintenance for us, less duplication in the ecosystem, other plugin can handle OS-level changes to permissions handling if those happen. Cons: one more package to import, and we're in trouble if the other plugin ever breaks or is discontinued
- Stay as-is: out of box experience is "enough", but for more control use permission handler. Pros: minimal maintenance, plugin comes "batteries included". Cons: will probably always be missing something people need unless we put the full effort in to replicate everything
- Put the full effort in, and implement everything relevant to notifications from permission handler. Pros: completely self contained. Cons: a lot of extra code that's not related to sending notifications
If I were designing this plugin from scratch I might say go with options 1 or 2. But given how far the plugin has come, we're basically at option 3 -- just need to check for permanently denied, whether to show rationale, and a button to go to system settings.
So it may not be so much work to just go all the way here. That being said, it is work that's duplicated across Android, iOS, and MacOS, and I personally wouldn't have the time or experience to implement all that.
Anyway I'm not the right person to make the final call, just offering my two cents.
Well written @Levi-Lesches
After reading the documentation did not catch this "downfall" before implementing in code. So if you are in the progress of rewriting documentation, this could be highlighted.
I do not like vague status regarding this, but in my test it seems that checkPermissions() "never" would return null either.
And after reading about iOS vs MacOS vs Android vs Linux vs Windows plugin todays solution is probably in the middle.
If the plugin is about to take on the web-support too, there is more in the mix :)
I (like many other) uses this plugin in combination with Firebase. So my simple "solution" to this was this:
//Three statuses; notDetermined = 100% chance of showing a dialog asking the user for permission.
enum LocalNotificationPermissionStatus { granted, denied, notDetermined }
//Get notification settings, if not determined the requestPermissions() will show a dialog
NotificationSettings settings = await FirebaseMessaging.instance.getNotificationSettings();
if(settings.authorizationStatus == AuthorizationStatus.notDetermined){
return LocalNotificationPermissionStatus.notDetermined;
}
//Return status of checkPermissions(), handle denied as "show phone notification settings"
//...
That been said, if the option 3 route is followed: Why should it not include a function to show system notification settings also? (which also required a second hand package today).
So in my eyes I would fall back to option 1; show local notifications on all platforms. Replacing all permission code with a simple canShowLocalnotifications() true/false.
The quirk here is more based on how the underlying platform works though I agree that there's room for improvement. The enum from the other package exists because it's a general abstraction and I would say has a bit of a problem on its own where denied currently translates to Apple's notDetermined status. Semantically they aren't the same. I'm happy for it change to be enum based and would appreciate PR on this. If it were done, I would suggest the values are more closer to the statuses you have in your last post @large or align with https://developer.apple.com/documentation/usernotifications/unauthorizationstatus where some will likely need to be documented as being specific to iOS/macOS (e.g. provisional)
This will a lengthier one so I'll summarise that after more thought, this scenario is one that can be covered by the permissions plugin
I forgot a level of nuance that you're looking at. What you're referring to is on checking the permissions to show notifications in general. This isn't available and would currently be where using the permissions plugin comes in. What is covered by the plugin was more on requesting permissions and when it comes to the iOS/macOS, what notification settings are enabled. The latter is more granular. Potentially a rename of the checkPermissions() method could have helped avoid this
Using this example from Apple, the equivalent here is the permissions plugin gives details on authorisation status, which refers to if general permissions were granted or not. This aligns with the enum you're referring to. The plugin covers the remaining portion through the checkPermissions() method to indicate if a notification triggered will trigger an alert, sound etc. To use Apple's terminology, it would be the difference between authorisation status and authorisation options. checkPermissions() is actually dealing with the latter that the problem here was more on naming.
With that in mind, I would say the plugin is more at option 2 that @Levi-Lesches has mentioned. There's enough APIs to get permissions so that notifications appear. The plugin reached the position it is in so that developers had enough to be able to get a notification appear without relying on other libraries. Android originally didn't require permissions. That was something Google enforced later on. Apple's own APIs effectively bundled getting the permission and specifying the settings in one API call (see https://developer.apple.com/documentation/usernotifications/unusernotificationcenter/requestauthorization(options:completionhandler:)
I'd say getting to the level of detail you're after would push it to option 3. I'd rather avoid it and it's common in other ecosystems to use a dedicated permissions library. The permissions plugin currently doesn't allow specifying the different settings/authorisation options though