MobiWeb Help

Notification Channel Management

Manage notification channels from website code through native bridges on Android and iOS.

This page documents the new v1 operations:

  • Create channel

  • List channels

  • Delete channel

Platform Model

  • Android maps directly to NotificationChannel.

  • iOS maps channel IDs to UNNotificationCategory (best-effort parity).

Because iOS does not support Android-style channel importance/sound behavior at the same level, treat iOS channel support as category registration for routing and compatibility.

Android

Bridge object: AndroidNotification

Methods

Method

Return

Description

createNotificationChannel(payloadJson)

string (JSON)

Creates or updates a channel on Android 8+

listNotificationChannels()

string (JSON)

Lists all app channels

deleteNotificationChannel(channelId)

string (JSON)

Deletes a channel by ID (except protected default channel)

createNotificationChannel payload

payloadJson is a JSON string with:

{ "channelId": "orders", "name": "Order Updates", "description": "Order lifecycle alerts", "importance": "high" }

Accepted importance values:

  • String: none, min, low, default, high, max

  • Number: Android NotificationManager importance int

Android response shapes

Create success:

{ "success": true, "channelId": "orders", "name": "Order Updates", "description": "Order lifecycle alerts", "importance": 4 }

List success:

{ "success": true, "channels": [ { "id": "default_channel", "name": "General Notifications", "description": "General app notifications", "importance": 4 }, { "id": "orders", "name": "Order Updates", "description": "Order lifecycle alerts", "importance": 4 } ] }

Delete success:

{ "success": true, "deleted": true, "channelId": "orders" }

Common error values:

  • bridge_unavailable

  • unsupported_android_version

  • channel_id_required

  • notification_manager_unavailable

  • default_channel_protected

  • create_failed

  • list_failed

  • delete_failed

iOS

Bridge object: AppleNotification

Methods

Method

Return

Description

AppleNotification.createChannel(payload)

void

Creates or updates an iOS channel mapping

AppleNotification.listChannels()

void

Requests channel list

AppleNotification.deleteChannel(channelId)

void

Deletes channel mapping

iOS methods are asynchronous. Results are emitted as browser events.

iOS payload for createChannel

{ "channelId": "orders", "name": "Order Updates", "description": "Order lifecycle alerts", "importance": 3 }

Stored fields:

  • id

  • name

  • description

  • importance

importance is currently stored for parity/documentation and future use, but iOS delivery behavior remains category-based.

iOS events

Event name

event.detail shape

Description

mobiweb:appleNotificationChannelCreated

{ success: boolean, updated?: boolean, channel?: object, error?: string }

Create/update result

mobiweb:appleNotificationChannelsListed

{ success: boolean, channels: object[] }

List result

mobiweb:appleNotificationChannelDeleted

{ success: boolean, deleted?: boolean, channelId?: string, error?: string }

Delete result

The channel registry is persisted in app storage and restored on app launch, then registered as UNNotificationCategory values.

Compatibility Notes

  • Android channel_id is the native routing key.

  • iOS local notifications now map channel_id to categoryIdentifier when category is not supplied.

  • Deleting a non-existent channel is treated as a successful no-op on both platforms.

  • Deleting Android default_channel is blocked.

Website Usage Examples

Android helper

function createAndroidChannel(input) { if (typeof AndroidNotification === 'undefined') return null; const raw = AndroidNotification.createNotificationChannel(JSON.stringify(input)); return JSON.parse(raw || '{}'); } function listAndroidChannels() { if (typeof AndroidNotification === 'undefined') return []; const raw = AndroidNotification.listNotificationChannels(); const result = JSON.parse(raw || '{}'); return result.channels || []; } function deleteAndroidChannel(channelId) { if (typeof AndroidNotification === 'undefined') return null; const raw = AndroidNotification.deleteNotificationChannel(channelId); return JSON.parse(raw || '{}'); }

iOS helper

function createIosChannel(input) { if (typeof AppleNotification === 'undefined') return; AppleNotification.createChannel(input); } function listIosChannels() { if (typeof AppleNotification === 'undefined') return; AppleNotification.listChannels(); } function deleteIosChannel(channelId) { if (typeof AppleNotification === 'undefined') return; AppleNotification.deleteChannel(channelId); } window.addEventListener('mobiweb:appleNotificationChannelCreated', (e) => { console.log('iOS channel create:', e.detail); }); window.addEventListener('mobiweb:appleNotificationChannelsListed', (e) => { console.log('iOS channel list:', e.detail.channels); }); window.addEventListener('mobiweb:appleNotificationChannelDeleted', (e) => { console.log('iOS channel delete:', e.detail); });
  1. Create channels during app startup or user/session initialization.

  2. Keep channel IDs stable and lowercase.

  3. Use channel_id consistently in push/local payloads.

  4. Keep an application-level fallback to default_channel on Android.

Publishing Notifications via FCM Proxy

To send a push notification to a specific channel created by the website:

Step 1: Create Channel (Website)

Call the bridge to create a channel with a stable ID:

// Android AndroidNotification.createNotificationChannel(JSON.stringify({ channelId: "order_updates", name: "Order Updates", description: "Notifications about your orders", importance: 4 })); // iOS AppleNotification.createChannel({ channelId: "order_updates", name: "Order Updates", description: "Notifications about your orders" });

Step 2: Send FCM Notification (Backend)

Include the channel_id in the FCM proxy payload's data object:

curl -X POST https://your-fcm-proxy/send \ -H "Content-Type: application/json" \ -d '{ "title": "Order Shipped", "subtitle": "Your order has shipped", "token": "device_fcm_token", "priority": "high", "data": { "channel_id": "order_updates", "url": "https://app.com/orders/123", "image": "https://app.com/order.jpg" } }'

Critical: The channel_id in your FCM payload must match the channelId you created via the bridge.

Step 3: Device Routes Notification Automatically

Android:

  • NotificationRenderer reads the channel_id from FCM payload

  • Creates notification using NotificationCompat.Builder(context, "order_updates")

  • Notification inherits all channel settings: sound, vibration, importance, LED color, etc.

iOS:

  • AppDelegate receives the notification with channel_id

  • Maps channel_idUNNotificationCategory identifier

  • Uses the pre-registered category (from app startup UserDefaults)

  • Notification displays with category-configured behavior

Channel Settings Inherited by Notification

Android Channel Property

iOS Equivalent

Inherited by Notification

importance (1-5)

Category behavior

Display priority, sound, interruption level

Sound

Notification sound

✓ Plays on device

Vibration

Haptic pattern

✓ Haptic feedback if enabled

Light color

LED indicator

✓ LED flash (Android only)

Allow bypass DND

Category

✓ Breaks through Do Not Disturb

Complete Example: Order Notifications

Website initialization (app startup):

function setupOrderNotificationChannel() { if (typeof AndroidNotification !== 'undefined') { AndroidNotification.createNotificationChannel(JSON.stringify({ channelId: "orders", name: "Order Alerts", description: "Updates about your purchases", importance: 4 // High = prominent, sound + vibration })); } if (typeof AppleNotification !== 'undefined') { AppleNotification.createChannel({ channelId: "orders", name: "Order Alerts", description: "Updates about your purchases" }); } } setupOrderNotificationChannel();

Backend sends notification:

{ "title": "Payment Received", "subtitle": "Thank you for your order #45678", "token": "...", "priority": "high", "data": { "channel_id": "orders", "url": "https://app.com/orders/45678", "amount": "$99.99" } }

Result: Notification appears with high-importance treatment, sound, vibration, and user can tap to view order details.

No FCM Proxy Changes Required

The FCM proxy already supports channel_id in data payloads. Both platforms automatically:

  • Read channel_id from the notification data

  • Map it to the locally-created channel/category

  • Inherit all configured channel behavior

The bridge is purely for creating channels with their settings; FCM proxy just targets them via channel_id.

10 May 2026