Deep dive into permissions in Ionic and Cordova

Yevhenii Smirnov
Yevhenii Smirnov
Feb 10 2023
Posted in Engineering & Technology

Notifications and Location permission requests

Deep dive into permissions in Ionic and Cordova

I'm back into my favorite blog post saga about permissions. Our Ionic and Cordova libraries did support location permissions already, but since we've added notifications permissions and updated location (SDK version 3.5.0), it's a good time to talk about those features. Also, you may want to check our previous blog posts about permissions in Android and Flutter.

Overview of available methods

Both location and notification modules, to help you deal with permissions, will have the following features:

Notifications

Check permission status

  • As you would expect, this method will check if permission is granted, denied, or permanently denied. Now while iOS is easy to detect if it is permanently denied, that's something tricky in Android. So at that point in Android you will get permanently denied ONLY if the device system version is 12 or lower, and because default permission status is granted, when we detect denied, that means the user switched it off in system settings.

Should show permission rationale

  • Not much description is needed as you are most probably familiar with this. This method will indicate whether you should or not show permission rationale in Android (True or False).
  • In iOS, it will always return False.

Present rationale

  • Android will present the rationale to the user, nothing will happen in iOS.

Request the permission

  • Will request, if possible, notifications permission. This method will return granted, denied, or permanently denied.
  • When the return is permanently denied, that means a permission request could not be done (no prompt was shown) and you should point the user to system settings.

Open app settings

  • Will forward the user to app settings. This is handy when we are dealing with permanently denied permission.

Location

When dealing with location permissions, we have to indicate what permission we are requesting (When in Use, Always or Bluetooth). We provide the same methods as for Notifications, with a small difference:

Check permission status

  • In iOS will return granted, denied, restricted, or permanently denied. In Android will return granted or denied.

Should show permission rationale, Present rationale, and Open app settings

  • With the same behavior.

Request permission

  • Same behavior with the exception we can get restricted status when dealing with iOS.

Important notes

  • In Android, as mentioned in the previous permissions blog post, which I highly recommend reading, you may get permanently denied if it is a first-time request and has been dismissed. It is also the behavior you will find in applications coming with Android OS.
  • In iOS, when requesting When in Use permission and the user chooses Allow only once, you will get granted status, as expected. But if afterwards, you request Always permission, that exact request will not get any answer. In the resume, technically you have When in Use permission, but it is only valid for that session and will reset to not determined next time.

Let's see a real example

Assuming we are building the Settings view for our app, and we use notifications and foreground/background location.

Independently of which of those permissions we are requesting, we should keep the same flow when possible.

Check permission status:

  async function checkNotificationsPermissionStatus() {
    try {
      const status = await NotificarePush.checkPermissionStatus();
      switch (status) {
        case PushPermissionStatus.GRANTED:
          // granted
          break;
        case PushPermissionStatus.DENIED:
          // denied
          break;
        case PushPermissionStatus.PERMANENTLY_DENIED: {
          // permanently denied
          break;
        }
      }
    } catch (e) {
      // Handle error
    }
  }

Request Permission:

  async function requestNotificationsPermission() {
    try {
      if (await NotificarePush.shouldShowPermissionRationale()) {
        await NotificarePush.presentPermissionRationale({
          title: 'title',
          message: 'message',
          buttonText: 'button text',
        });
      }

      const status = await NotificarePush.requestPermission();
      if (status == PushPermissionStatus.GRANTED) {
        // Enable remote notifications
        return;
      }

      if (status == PushPermissionStatus.PERMANENTLY_DENIED) {
        // TODO: Show some informational UI, educating the user to change the permission via the Settings app.
        await NotificarePush.openAppSettings();
      }
    } catch (e) {
      // Handle error
    }
  }

Let's go through:

  • In the first method:
    • We check the status and act accordingly.
  • Second method:
    • When Should show rationale returns True, we Present the rationale before requesting permission.
    • Request the permission and if granted, enable notifications/location updates. When you get permanently denied, it's time to redirect the user to OS Settings. I do recommend you show some sort of explaining dialog, both Android and iOS, before the redirect.

In the example above I'm checking and requesting notifications permission, but you could easily adapt it to the location.

Conclusion

With these provided methods, you should be able to handle most situations when you have to deal with permissions.

As always, we hope this post was helpful and feel free to share with us your ideas or feedback via our Support Channel.

Keep up-to-date with the latest news