Skip to content
Shiny.NET

Notifications

NuGet package Shiny.AppDeviceBridge.Notifications

The notifications bridge sends local notifications now, on a schedule, repeating or at a geofence, lists and cancels pending ones, sets the badge and manages channels. A tap reaches the page, or background.js when no page is open. It’s backed by Shiny.Notifications.

Android, iOS, Mac Catalyst, macOS, Windows, and Linux through Shiny.Notifications.Linux.

Terminal window
dotnet add package Shiny.AppDeviceBridge.Notifications
builder.UseAppDeviceBridge(
bridge => bridge.AddNotificationsBridge(),
webApp => { /* … */ }
);
Client C# TypeScript
INotificationsBridge AddNotificationsBridgeClient() NotificationsBridge

What send takes, and how taps reach background.js, is on Native Calls & Background.

import { NotificationsBridge } from "@shinyorg/appdevicebridge";
const notifications = new NotificationsBridge();
await notifications.requestAccess({ timeSensitive: false });
const { id } = await notifications.send({
title: "Order ready",
message: "Table 12 is up",
scheduleDate: new Date(Date.now() + 60_000),
data: { order: "1234" }
});
await notifications.onEntry(n => navigate(`/orders/${n.data.order}`)); // the user tapped it
await notifications.setBadge({ value: 3 });

A channel can carry action buttons. requiresUnlock makes the user unlock the device before the action runs — use it for actions with a real-world effect, such as opening a garage door. It applies on iOS, Mac Catalyst and macOS, and on Android 12 and later; older Android versions run the action without asking, and Windows and Linux ignore it.

await notifications.addChannel({
identifier: "garage",
actions: [
{ identifier: "open", title: "Open Garage", actionType: "OpenApp", requiresUnlock: true },
{ identifier: "dismiss", title: "Dismiss", actionType: "Destructive", requiresUnlock: false }
]
});

The tapped action reaches notification.entry as action.

GET/_bridge/notifications#

Permission and what this platform supports.

C#INotificationsBridge.GetStatusAsyncTSNotificationsBridge.getStatus
Response
200 NotificationStatus
NotificationStatus · 6 fields
accessAccessState
badgebooleanWhether the app badge can be read and set.
entrybooleanWhether taps are reported.
receivedbooleanWhether notifications arriving while the app is open are reported.
geofencesbooleanWhether a notification can wait for the device to enter an area.
imagesbooleanWhether a notification can carry an image.
POST/_bridge/notifications/access#

Requests permission, optionally for time-sensitive and location-aware notifications too.

C#INotificationsBridge.RequestAccessAsyncTSNotificationsBridge.requestAccess
Body
application/json · NotificationAccessRequest
NotificationAccessRequest · 2 fields
timeSensitiveboolean
locationAwareboolean
Response
200 NotificationAccessResult
NotificationAccessResult · 1 field
accessAccessState
POST/_bridge/notifications/send#

Sends or schedules a notification. Fails with 400 for an invalid one, such as a date already past.

C#INotificationsBridge.SendAsyncTSNotificationsBridge.send
Body
application/json · NotificationRequest
NotificationRequest · 12 fields
messagestringAt most 4,000 characters.
titlestring | null
subtitlestring | null
idnumber | nullReplaces a notification with the same id; assigned when null.
channelstring | nullAn Android channel identifier.
threadstring | nullGroups notifications together.
badgeCountnumber | null
scheduleDateDate | string | nullShow it then rather than now.
repeatNotificationRepeat | null
geofenceNotificationGeofence | null
imageBridgeFile | nullA .png, .jpg, .gif or .heic of at most 10 MB in a file root.
dataRecord<string, string> | nullComes back on the tap.
Response
200 NotificationSent
NotificationSent · 1 field
idnumber
Errors
400Bad request
GET/_bridge/notifications/pending#

Scheduled notifications that have not been shown yet.

C#INotificationsBridge.GetPendingAsyncTSNotificationsBridge.getPending
Response
200 PendingNotification[]
PendingNotification · 11 fields
idnumber
titlestring | null
messagestring | null
channelstring | null
threadstring | null
badgeCountnumber | null
scheduleDatestring | null
repeatNotificationRepeat | null
geofenceNotificationGeofence | null
fromWebAppbooleanWhether the web app sent it, rather than the native app.
dataRecord<string, string>
DELETE/_bridge/notifications#

Cancels pending notifications, clears displayed ones, or both.

C#INotificationsBridge.CancelAllAsyncTSNotificationsBridge.cancelAll
ParameterInType
scopequeryNotificationCancelScopeoptional
Response
204 No content
DELETE/_bridge/notifications/{id}#

Cancels one notification.

C#INotificationsBridge.CancelAsyncTSNotificationsBridge.cancel
ParameterInType
idpathnumberrequired
Response
204 No content
GET/_bridge/notifications/badge#

The app icon's badge number.

C#INotificationsBridge.GetBadgeAsyncTSNotificationsBridge.getBadge
Response
200 NotificationBadge
NotificationBadge · 1 field
valuenumber
PUT/_bridge/notifications/badge#

Sets the app icon's badge number, 0–99,999.

C#INotificationsBridge.SetBadgeAsyncTSNotificationsBridge.setBadge
Body
application/json · NotificationBadge
NotificationBadge · 1 field
valuenumber
Response
204 No content
POST/_bridge/notifications/channels#

Adds or replaces a channel.

C#INotificationsBridge.AddChannelAsyncTSNotificationsBridge.addChannel
Body
application/json · NotificationChannel
NotificationChannel · 5 fields
identifierstring1–64 letters, digits, ., - or _.
descriptionstring | null
importanceChannelImportance
soundChannelSound
actionsNotificationChannelAction[] | null
Response
200 NotificationChannel
NotificationChannel · 5 fields
identifierstring1–64 letters, digits, ., - or _.
descriptionstring | null
importanceChannelImportance
soundChannelSound
actionsNotificationChannelAction[] | null
DELETE/_bridge/notifications/channels/{identifier}#

Removes a channel.

C#INotificationsBridge.RemoveChannelAsyncTSNotificationsBridge.removeChannel
ParameterInType
identifierpathstringrequired
Response
204 No content
EVENTnotification.entry#

The user tapped a notification, or one of its actions.

C#INotificationsBridge.OnEntryAsyncTSNotificationsBridge.onEntry
Payload
NotificationEvent
idnumber
titlestring | null
messagestring | null
channelstring | null
threadstring | null
dataRecord<string, string>
actionstring | nullThe action chosen, when the user picked one rather than the notification itself.
textstring | nullWhat the user typed, for a text reply action.
EVENTnotification.received#

A notification arrived while the app was open. Apple platforms only.

C#INotificationsBridge.OnReceivedAsyncTSNotificationsBridge.onReceived
Payload
NotificationEvent
idnumber
titlestring | null
messagestring | null
channelstring | null
threadstring | null
dataRecord<string, string>
actionstring | nullThe action chosen, when the user picked one rather than the notification itself.
textstring | nullWhat the user typed, for a text reply action.

JSON property names are camelCase and enums travel as their names. A ? marks a property the payload may omit;| null one that may be null.

NotificationStatusobject#
accessAccessState
badgebooleanWhether the app badge can be read and set.
entrybooleanWhether taps are reported.
receivedbooleanWhether notifications arriving while the app is open are reported.
geofencesbooleanWhether a notification can wait for the device to enter an area.
imagesbooleanWhether a notification can carry an image.
AccessStateenum#

Where a permission stands. Reported by every bridge that needs one; the names match Shiny's own.

"Unknown""NotSupported""NotSetup""Disabled""Restricted""Denied""Available"
NotificationAccessRequestobject#
timeSensitive?boolean
locationAware?boolean
NotificationRequestobject#

A notification to send.

messagestringAt most 4,000 characters.
title?string | null
subtitle?string | null
id?number | nullReplaces a notification with the same id; assigned when null.
channel?string | nullAn Android channel identifier.
thread?string | nullGroups notifications together.
badgeCount?number | null
scheduleDate?Date | string | nullShow it then rather than now.
repeat?NotificationRepeat | null
geofence?NotificationGeofence | null
image?BridgeFile | nullA .png, .jpg, .gif or .heic of at most 10 MB in a file root.
data?Record<string, string> | nullComes back on the tap.
NotificationRepeatobject#

A repeating schedule: every intervalSeconds, or at timeOfDay, optionally on one day.

intervalSecondsnumber | null
timeOfDaystring | null
dayOfWeek("Sunday" | "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" | "Saturday") | null
NotificationGeofenceobject#

Show the notification when the device enters an area.

latitudenumber
longitudenumber
radiusMetersnumber
repeatboolean
BridgeFileobject#

A file the page can reach through the files bridge: a named root and a path inside it. Bridges that take or return a file use this, so nothing reaches the page that /_bridge/files would not also serve.

rootstring
pathstring
NotificationSentobject#
idnumber
PendingNotificationobject#
idnumber
titlestring | null
messagestring | null
channelstring | null
threadstring | null
badgeCountnumber | null
scheduleDatestring | null
repeatNotificationRepeat | null
geofenceNotificationGeofence | null
fromWebAppbooleanWhether the web app sent it, rather than the native app.
dataRecord<string, string>
NotificationCancelScopeenum#
"All""Pending""Displayed"
NotificationBadgeobject#
valuenumber
ChannelImportanceenum#
"Low""Normal""High""Critical"
ChannelSoundenum#
"None""Default""High""Custom"
NotificationChannelActionobject#
identifierstring
titlestring
actionTypeChannelActionType
requiresUnlockbooleanThe device must be unlocked before the action runs — for actions with a real-world effect, such as "Open Garage". Combines with any ChannelActionType. Apple: always. Android: 12 (API 31) and later; older versions run the action without asking. Ignored on Windows and Linux.
ChannelActionTypeenum#
"TextReply""Destructive""OpenApp""None"
NotificationEventobject#

A notification the user tapped or that arrived while the app was open.

idnumber
titlestring | null
messagestring | null
channelstring | null
threadstring | null
dataRecord<string, string>
actionstring | nullThe action chosen, when the user picked one rather than the notification itself.
textstring | nullWhat the user typed, for a text reply action.

These routes sit under AppDeviceBridgePolicies.Bridges like every other bridge: callers on this device by default. See Security.