Skip to content

Commit 9ee657e

Browse files
committed
fix iOS denied notificationPermissionChange
On iOS `navigator.permissions.query({ name: 'notifications' }`).onchange does not fire due to a bug with the browser. To account for this we are calling our triggerNotificationPermissionChanged event every time the native notification prompt is answered or dismissed. This however does create duplicate events so this commit adds logic to PermissionUtils.triggerNotificationPermissionChanged to prevent this. Tested event now fire exactly once on iOS 16.5. Tested both for accepting and declining. Also confirmed Chrome on macOS still works
1 parent 6527abf commit 9ee657e

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

src/managers/SubscriptionManager.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -334,15 +334,12 @@ export class SubscriptionManager {
334334
const permission = await SubscriptionManager.requestPresubscribeNotificationPermission();
335335

336336
/*
337-
Notification permission changes are already broadcast by the page's
338-
notificationpermissionchange handler. This means that allowing or
339-
denying the permission prompt will cause double events. However, the
340-
native event handler does not broadcast an event for dismissing the
337+
The native event handler does not broadcast an event for dismissing the
341338
prompt, because going from "default" permissions to "default"
342339
permissions isn't a change. We specifically broadcast "default" to "default" changes.
343340
*/
344-
if (permission === NotificationPermission.Default)
345-
await PermissionUtils.triggerNotificationPermissionChanged(true);
341+
const forcePermissionChangeEvent = permission === NotificationPermission.Default
342+
await PermissionUtils.triggerNotificationPermissionChanged(forcePermissionChangeEvent);
346343

347344
// If the user did not grant push permissions, throw and exit
348345
switch (permission) {

src/utils/PermissionUtils.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,20 @@ import Database from "../services/Database";
22
import Event from '../Event';
33

44
export class PermissionUtils {
5+
6+
// This flag prevents firing the NATIVE_PROMPT_PERMISSIONCHANGED event twice
7+
// We use multiple APIs:
8+
// 1. Notification.requestPermission callback
9+
// 2. navigator.permissions.query({ name: 'notifications' }`).onchange
10+
// Some browsers support both, while others only support Notification.requestPermission
11+
private static executing = false;
12+
513
public static async triggerNotificationPermissionChanged(updateIfIdentical = false) {
14+
if (PermissionUtils.executing) {
15+
return;
16+
}
17+
PermissionUtils.executing = true;
18+
619
const newPermission = await OneSignal.privateGetNotificationPermission();
720
const previousPermission = await Database.get('Options', 'notificationPermission');
821

@@ -13,5 +26,6 @@ export class PermissionUtils {
1326

1427
await Database.put('Options', { key: 'notificationPermission', value: newPermission });
1528
Event.trigger(OneSignal.EVENTS.NATIVE_PROMPT_PERMISSIONCHANGED, { to: newPermission });
29+
PermissionUtils.executing = false;
1630
}
1731
}

0 commit comments

Comments
 (0)