diff --git a/native/push/push-handler.react.js b/native/push/push-handler.react.js --- a/native/push/push-handler.react.js +++ b/native/push/push-handler.react.js @@ -113,6 +113,7 @@ currentState: ?string = getCurrentLifecycleState(); appStarted = 0; androidNotificationsEventSubscriptions: Array = []; + androidNotificationsPermissionPromise: ?Promise = undefined; initialAndroidNotifHandled = false; openThreadOnceReceived: Set = new Set(); lifecycleSubscription: ?EventSubscription; @@ -135,7 +136,7 @@ ), commIOSNotificationsEventEmitter.addListener( 'remoteNotificationsRegistrationFailed', - this.failedToRegisterPushPermissions, + this.failedToRegisterPushPermissionsIOS, ), commIOSNotificationsEventEmitter.addListener( 'notificationReceivedForeground', @@ -323,9 +324,22 @@ } async ensureAndroidPushNotifsEnabled() { - const hasPermission = await CommAndroidNotifications.hasPermission(); + const permissionPromisesResult = await Promise.all([ + CommAndroidNotifications.hasPermission(), + CommAndroidNotifications.canRequestNotificationsPermissionFromUser(), + ]); + + let [hasPermission] = permissionPromisesResult; + const [, canRequestPermission] = permissionPromisesResult; + + if (!hasPermission && canRequestPermission) { + const permissionResponse = + await this.requestAndroidNotificationsPermission(); + hasPermission = permissionResponse; + } + if (!hasPermission) { - this.failedToRegisterPushPermissions(); + this.failedToRegisterPushPermissionsAndroid(!canRequestPermission); return; } @@ -333,10 +347,22 @@ const fcmToken = await CommAndroidNotifications.getToken(); await this.handleAndroidDeviceToken(fcmToken); } catch (e) { - this.failedToRegisterPushPermissions(); + this.failedToRegisterPushPermissionsAndroid(!canRequestPermission); } } + requestAndroidNotificationsPermission = () => { + if (!this.androidNotificationsPermissionPromise) { + this.androidNotificationsPermissionPromise = (async () => { + const notifPermission = + await CommAndroidNotifications.requestNotificationsPermission(); + this.androidNotificationsPermissionPromise = undefined; + return notifPermission; + })(); + } + return this.androidNotificationsPermissionPromise; + }; + handleAndroidDeviceToken = async (deviceToken: string) => { this.registerPushPermissions(deviceToken); await this.handleInitialAndroidNotification(); @@ -374,15 +400,22 @@ ); } - failedToRegisterPushPermissions = () => { + failedToRegisterPushPermissionsIOS = () => { this.setDeviceToken(null); if (!this.props.loggedIn) { return; } - const deviceType = Platform.OS; - if (deviceType === 'ios') { - iosPushPermissionResponseReceived(); - } else { + iosPushPermissionResponseReceived(); + }; + + failedToRegisterPushPermissionsAndroid = ( + shouldShowAlertOnAndroid: boolean, + ) => { + this.setDeviceToken(null); + if (!this.props.loggedIn) { + return; + } + if (shouldShowAlertOnAndroid) { this.showNotifAlertOnAndroid(); } };