MobiWeb Help

Notifications & FCM Token

Bridges for checking/requesting push notification permission and retrieving the Firebase Cloud Messaging (FCM) token.

Android

Bridge object: AndroidNotification

Methods

Method

Return

Description

requestNotificationPermission()

void

Prompts the user for notification permission (Android 13+)

getNotificationPermissionStatus()

string (JSON)

Returns current notification permission/settings status

openNotificationSettings()

void

Opens the app's notification settings page

setNotifyOnStartup(enabled)

void

Persists whether to request notification on app start

getNotifyOnStartup()

boolean

Returns the persisted notify-on-startup setting (default false)

getFirebaseToken()

string

Returns the FCM token synchronously (may be empty)

requestFirebaseToken()

void

Requests a fresh token; result dispatched via event

sendLocalNotification(payload)

void

Schedules/displays a local notification from website payload

createNotificationChannel(payloadJson)

string (JSON)

Creates/updates a notification channel (Android 8+)

listNotificationChannels()

string (JSON)

Lists app notification channels

deleteNotificationChannel(channelId)

string (JSON)

Deletes a channel by ID (except protected default channel)

Events

Listen for these CustomEvents on window:

Event name

event.detail shape

Description

mobiweb:notificationPermission

{ granted: boolean }

Result of permission request

mobiweb:fcmToken

{ token: string, oldtoken?: string }

New or refreshed FCM token

mobiweb:cookiesCleared

{ success: boolean }

Result of cookie clearing

Example

// Check current status const status = JSON.parse(AndroidNotification.getNotificationPermissionStatus()); console.log('Notifications enabled:', status.notificationsEnabled); // Request permission AndroidNotification.requestNotificationPermission(); // Listen for result window.addEventListener('mobiweb:notificationPermission', (e) => { console.log('Granted:', e.detail.granted); }); // Get token synchronously const token = AndroidNotification.getFirebaseToken(); // Request token, listen for event AndroidNotification.requestFirebaseToken(); window.addEventListener('mobiweb:fcmToken', (e) => { console.log('FCM token:', e.detail.token); });

iOS

Bridge object: AppleNotification (injected shim)

The iOS shim exposes the same intent as Android but communicates via WKScriptMessageHandler.

Methods

Method

Return

Description

AppleNotification.requestNotificationPermission()

void

Prompts the user for notification permission (alert, badge, sound)

AppleNotification.requestCriticalAlertsPermission()

void

Prompts the user for the Critical Alerts permission. Always available on the shim; result is reported asynchronously via mobiweb:appleCriticalAlertsPermissionResult. If the build's provisioning profile lacks the com.apple.developer.usernotifications.critical-alerts entitlement, the event detail will be { granted: false, criticalAlertSetting: 'notSupported' }.

AppleNotification.getNotificationPermissionStatus()

Promise<object>

Resolves current notification permission/settings status, including Critical Alerts status

AppleNotification.requestToken()

void

Requests an FCM token

AppleNotification.getToken()

string

Returns the cached FCM token synchronously

AppleNotification.isTokenValid()

boolean

Returns whether the cached token is valid

AppleNotification.sendLocalNotification(payload)

void

Schedules/displays a local notification from website payload

AppleNotification.createChannel(payload)

void

Creates/updates iOS channel mapping (UNNotificationCategory)

AppleNotification.listChannels()

void

Lists persisted iOS channel mappings via event

AppleNotification.deleteChannel(channelId)

void

Deletes iOS channel mapping via event

Events

Event name

event.detail shape

Description

mobiweb:appleNotificationPermissionResult

{ granted: boolean }

Result of standard notification permission request

mobiweb:appleCriticalAlertsPermissionResult

{ granted: boolean, criticalAlertSetting?: 'enabled' \| 'disabled' \| 'notSupported' \| 'unknown' }

Result of Critical Alerts permission request. granted: false + criticalAlertSetting: 'notSupported' indicates the entitlement is missing from the installed build. granted: false with criticalAlertSetting: 'disabled' means the user declined.

mobiweb:appleNotificationPermissionStatus

{ notificationsEnabled: boolean, authorizationStatus: string, alertSetting: string, badgeSetting: string, soundSetting: string, criticalAlertsEnabled: boolean, criticalAlertSetting: string }

Current notification settings status. Includes requestId when triggered by getNotificationPermissionStatus().

mobiweb:appleNotificationToken

{ token: string, oldtoken?: string }

New or refreshed FCM/APNs token

Example

// Check current status (iOS) const status = await AppleNotification.getNotificationPermissionStatus(); console.log('Notifications enabled:', status.notificationsEnabled); console.log('Critical alerts enabled:', status.criticalAlertsEnabled); // Request permission (iOS) AppleNotification.requestNotificationPermission(); window.addEventListener('mobiweb:appleNotificationPermissionResult', (e) => { console.log('Granted:', e.detail.granted); }); // Request Critical Alerts — always available; inspect the event detail for outcome window.addEventListener('mobiweb:appleCriticalAlertsPermissionResult', (e) => { const { granted, criticalAlertSetting } = e.detail || {}; if (granted) { console.log('Critical alerts granted'); } else if (criticalAlertSetting === 'notSupported') { console.warn('Critical alerts entitlement missing from this build'); } else { console.log('Critical alerts denied:', criticalAlertSetting); } }, { once: true }); AppleNotification.requestCriticalAlertsPermission(); // Get token synchronously const token = AppleNotification.getToken(); // Request token via event AppleNotification.requestToken(); window.addEventListener('mobiweb:appleNotificationToken', (e) => { console.log('Token:', e.detail.token); });

Local Notification Payload

sendLocalNotification(payload) accepts notification configuration at the root level (same keys currently used by push data payloads) plus optional custom data and trigger settings.

{ title: 'Payment Reminder', body: 'Tap to complete your payment', // Existing notification config keys still work (sound, silent, badge, color, group, etc.) sound: 'default', data: { url: 'https://example.com/pay/123', orderId: '123' }, trigger: { // 'immediate' | 'delay' | 'time' | 'exit' | 'home' type: 'delay', delayMs: 10_000 // delayMs also works with 'home' and 'exit' // For specific time use: at: Date.now() + 60_000 } }

Trigger options:

Trigger

Payload example

Immediate

{ trigger: { type: 'immediate' } } or omit trigger

Delay

{ trigger: { type: 'delay', delayMs: 5000 } }

Specific time

{ trigger: { type: 'time', at: Date.now() + 60000 } }

On home screen

{ trigger: { type: 'home' } }

On home screen + delay

{ trigger: { type: 'home', delayMs: 5000 } }

On app exit

{ trigger: { type: 'exit' } }

On app exit + delay

{ trigger: { type: 'exit', delayMs: 5000 } }

Behavior notes:

  • Custom data is preserved in the native notification payload.

  • Passing data.url opens that URL on notification tap using the same current tap-navigation implementation.

Permission Status Shape

Android getNotificationPermissionStatus() returns a JSON string:

{ "platform": "android", "notificationsEnabled": true, "runtimePermissionGranted": true, "appNotificationsEnabled": true }

On Android 12 and older, runtimePermissionGranted is always true because the POST_NOTIFICATIONS runtime permission does not exist. notificationsEnabled is true only when the runtime permission is granted and app notifications are enabled in system settings.

iOS getNotificationPermissionStatus() resolves to the same object also dispatched through mobiweb:appleNotificationPermissionStatus:

{ "platform": "ios", "notificationsEnabled": true, "authorizationStatus": "authorized", "alertSetting": "enabled", "badgeSetting": "enabled", "soundSetting": "enabled", "criticalAlertsEnabled": false, "criticalAlertSetting": "notSupported" }

notificationsEnabled is true for authorized, provisional, or ephemeral authorization. Critical Alerts require criticalAlertsEnabled: true; criticalAlertSetting: "notSupported" means the installed build lacks the Apple-approved entitlement/provisioning support.

Channel Management

For complete channel-management payloads, response/event schemas, and platform compatibility notes, see Notification Channel Management.

Publishing to Channels via FCM Proxy

Once channels are created, your FCM proxy backend can target them by including channel_id in the notification's data payload:

{ "title": "Order Shipped", "subtitle": "Your order has shipped", "token": "...", "data": { "channel_id": "order_updates", "url": "https://app.com/orders/123" } }

The device automatically routes the notification to the specified channel, inheriting its sound, vibration, importance, and other settings. See Publishing via FCM Proxy for full details and examples.

Cross-platform Notification Helper

function requestNotificationPermission() { if (typeof AndroidNotification !== 'undefined') { AndroidNotification.requestNotificationPermission(); window.addEventListener('mobiweb:notificationPermission', (e) => { console.log('Android granted:', e.detail.granted); }, { once: true }); } else if (typeof AppleNotification !== 'undefined') { AppleNotification.requestNotificationPermission(); window.addEventListener('mobiweb:appleNotificationPermissionResult', (e) => { console.log('iOS granted:', e.detail.granted); }, { once: true }); } } function sendLocalNotification(payload) { if (typeof AndroidNotification !== 'undefined') { AndroidNotification.sendLocalNotification(payload); } else if (typeof AppleNotification !== 'undefined') { AppleNotification.sendLocalNotification(payload); } } function openNotificationSettings() { if (typeof AndroidNotification !== 'undefined' && typeof AndroidNotification.openNotificationSettings === 'function') { AndroidNotification.openNotificationSettings(); } } async function getNotificationPermissionStatus() { if (typeof AndroidNotification !== 'undefined') { return JSON.parse(AndroidNotification.getNotificationPermissionStatus()); } if (typeof AppleNotification !== 'undefined') { return AppleNotification.getNotificationPermissionStatus(); } return null; }
21 May 2026