Notifications API
Local reminders, native push, topic state, badges, and tap navigation.
internalPlugins.notifications enables local notifications, badges, and network. internalPlugins.pushNotifications also enables Firebase messaging and topic storage. Dependencies are @capacitor/local-notifications@8.3.1, @capawesome/capacitor-badge@8.0.4, @capacitor/network@8.0.1, and, for push, @capacitor-firebase/messaging@8.5.2.
Client operations
| Export | Input | Success value |
|---|---|---|
checkNotificationPermission | Effect value | "granted", "denied", or "prompt" |
requestNotificationPermission | Effect value | Same permission union |
checkExactAlarmPermission | Effect value | "granted", "denied", or "not-required" |
requestExactAlarmPermission | Effect value | Same exact-alarm union |
scheduleNotification(notification) | LocalNotification | NotificationScheduleResult |
cancelNotification(id) | Notification ID | Void |
registerPush | Effect value | FCM token string |
subscribeToTopic(topic) | Topic string | Void |
unsubscribeFromTopic(topic) | Topic string | Void |
getNotificationTopics | Effect value | Confirmed topic list on this installation |
isSubscribedToTopic(topic) | Topic string | Boolean |
setNotificationBadge(count) | Nonnegative integer | Void |
clearNotificationBadge | Effect value | Void, equivalent to count zero |
Permission, scheduling, cancellation, and push registration depend on Bridge | BrowserNotifications. Topic and badge operations depend on Bridge. notificationsLive(effect) provides BrowserNotificationsLive. browserNotificationsLayer and BrowserNotifications support injected browser behavior.
Input schemas
LocalNotificationSchema has required id, title, and delaySeconds, plus optional body and route.
| Field | Constraint |
|---|---|
id | Integer from 1 through 2147483647 |
title | Nonempty string |
body | Optional string |
delaySeconds | Finite number greater than zero |
route | Optional app-relative path starting with one /; no backslash, whitespace, or control characters |
NotificationRouteSchema validates the route. TopicSchema accepts 1 to 900 characters matching letters, digits, _, ., ~, %, or -. The /topics/ prefix is not part of this input. NotificationPermissionSchema validates the permission union.
Native scheduling requests permission when it is prompt. A denied permission fails with PermissionDenied. Browsers schedule only while the page remains open. Native push and topics are unavailable in browsers. Topic lookup reports local confirmed state, not an FCM server query. Badges depend on native platform and launcher support.
Exact alarms and schedule results
ExactAlarmPermissionSchema validates "granted" | "denied" | "not-required". Display permission remains separate.
| Capability | Android | iOS | Browser |
|---|---|---|---|
| Exact-alarm check | checkExactNotificationSetting | "not-required", no native call | "not-required", no native call |
| Exact-alarm request | changeExactNotificationSetting; Android 12+ opens Alarms & reminders settings and returns the setting on return | "not-required" | "not-required" |
| Older Android | "granted"; no special access required | Not applicable | Not applicable |
| Local reminders | Native scheduling | Native scheduling | Only while page stays open |
| Push and topics | Firebase messaging | Firebase messaging | Unavailable |
| Badges | Launcher-dependent | Platform support | Unavailable |
| Exact-alarm rule | Behavior |
|---|---|
| Declared permission | Plugin 8.3.1 declares SCHEDULE_EXACT_ALARM; merged by Android, unchanged by Radical |
| Android 12 and 13 | Granted at install; user can revoke |
| Android 14+ | Denied for most new installs targeting API 33+; exemptions and OS-upgrade grants may preserve access |
| Scheduling without access | Capacitor may open settings, then accept an inexact alarm if access remains denied |
| Later grant | Does not upgrade existing inexact alarms |
| Revocation | Android cancels future exact alarms |
USE_EXACT_ALARM | Declared by neither Radical nor the plugin; Play restricts it to qualifying core alarm and calendar cases |
| Timing | No permission value or missing warning guarantees delivery time |
NotificationScheduleResultSchema field | Contract |
|---|---|
notifications | Array of { id: number } |
warning | Optional { code: string, message: string }, type NotificationScheduleWarning |
warning.code: "OS-PLUG-LNOT-0017" | Android accepted an inexact alarm because exact access was missing |
| Other warning codes | Preserved |
| Browser result | Accepted ID without warning |
The result type is NotificationScheduleResult. Exact-alarm operations require Bridge; denial is a success value. Requesting access before scheduling avoids consuming the delay in settings.
Policy sources: Android permission changes, Android alarm behavior, and Play permission restrictions.
Navigation watcher
| Contract | Value |
|---|---|
watchNotificationNavigation({ appId, push?, onError? }) | Scoped, long-lived Effect requiring Bridge, RadicalAdapter, NotificationSnapshots |
push | Defaults to false |
| Tap handling | Validate route; try exact stored snapshot offline; otherwise adapter navigation |
NotificationSnapshotsLive | Browser cache and browser network service; still requires Bridge |
restore(route, appId) | Whether full-document restoration started |
| Browser event | radical-notification |
Errors and React hooks
| Error | Meaning |
|---|---|
PermissionDenied | Notification permission denied |
Unavailable | Invalid IDs, routes, topic names, badge counts, or out-of-range dates |
MissingPushConfiguration | Missing native Firebase setup; carries reason |
BridgeCallFailed | Unknown native failure |
BridgeDecodeError | Malformed result |
| Exact-alarm errors | Same typed bridge errors |
useNotificationPermission() exposes check() and request(). useExactAlarmPermission() checks on mount and exposes check() and request(), with the exact-alarm union in value. useNotifications() exposes schedule, cancel, badge, push, and topic actions. Schedule actions retain NotificationScheduleResult in value, including warnings. Topic actions return the updated confirmed list in value.
Source: notification implementation.