Name Date Size #Lines LOC

..26-Sep-2023-

android/H26-Sep-2023-8,2146,000

build/H26-Sep-2023-4,1422,304

ios/H26-Sep-2023-2,9952,368

plugin/H26-Sep-2023-910744

src/H26-Sep-2023-4,3102,685

.eslintrc.jsH A D26-Sep-2023103 31

.npmignoreH A D26-Sep-2023183 128

CHANGELOG.mdH A D26-Sep-202333.6 KiB469273

README.mdH A D26-Sep-202381.8 KiB2,0041,481

app.plugin.jsH A D26-Sep-202362 21

babel.config.jsH A D26-Sep-2023104 31

expo-module.config.jsonH A D26-Sep-20231.1 KiB2120

package.jsonH A D26-Sep-20231.5 KiB6160

tsconfig.jsonH A D26-Sep-2023217 109

README.md

1<p>
2  <a href="https://docs.expo.dev/versions/latest/sdk/notifications/">
3    <img
4      src="../../.github/resources/expo-notifications.svg"
5      alt="expo-notifications"
6      height="64" />
7  </a>
8</p>
9
10Provides an API to fetch push notification tokens and to present, schedule, receive and respond to notifications.
11
12## Features
13
14- �� schedule a one-off notification for a specific date, or some time from now,
15- �� schedule a notification repeating in some time interval (or a calendar date match on iOS),
16- 1️⃣ get and set application badge icon number,
17- �� fetch a native device push token so you can send push notifications with FCM and APNS,
18- �� fetch an Expo push token so you can send push notifications with Expo,
19- �� listen to incoming notifications in the foreground and background,
20- �� listen to interactions with notifications (tapping or dismissing),
21- �� handle notifications when the app is in foreground,
22- �� imperatively dismiss notifications from Notification Center/tray,
23- �� create, update, delete Android notification channels,
24- �� set custom icon and color for notifications on Android.
25
26# Installation in managed Expo projects
27
28Please refer to the [installation instructions in the Expo documentation](https://docs.expo.dev/versions/latest/sdk/notifications/#installation).
29
30# Installation in bare React Native projects
31
32For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
33
34### Add the package to your npm dependencies
35
36```
37npx expo install expo-notifications
38```
39
40### Configure for iOS
41
42Run `npx pod-install` after installing the npm package.
43
44In order to be able to receive push notifications on the device:
45
46- open Xcode workspace from your `ios` folder
47- select your project from the _Navigator_ pane
48- switch to _Signing & Capabilities_ tab
49- ensure that the _Push notifications_ capability is present (if it's not, click the "+ Capability" button and add the capability to the project).
50
51### Configure for Android
52
53In order to be able to receive push notifications on the device ensure that your project is set up for Firebase. For more information on how to do it, see [this guide](https://docs.expo.dev/guides/setup-native-firebase/#bare-workflow-setup).
54
55This module requires permission to subscribe to device boot. It's used to setup the scheduled notifications right after the device (re)starts. The `RECEIVE_BOOT_COMPLETED` permission is added automatically.
56
57**Note:** Starting from Android 12 (API level 31), to schedule the notification that triggers at the exact time, you need to add `<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>` to **AndroidManifest.xml**. You can read more about the exact alarm permission [here](https://developer.android.com/about/versions/12/behavior-changes-12#exact-alarm-permission).
58
59<details><summary><strong>Expand to view how the notification icon and the default color can be customized in a plain React Native app</strong></summary> <p>
60
61- **To customize the icon**:
62
63  You can customize two icons: the default and the large one. See [the Android documentation](https://developer.android.com/guide/topics/ui/notifiers/notifications#Templates) for more details. The steps for them are very similar. The only difference is the tag in the second step.
64
65  1. You will need to ensure that the icon is properly set up and added the project. To read more on how to create a notification icon and add it to the project check out the [“Create notification icon” section](https://developer.android.com/studio/write/image-asset-studio#create-notification) at the official Android guide. Remember the name you use for the icon asset, you will need it later!
66  2. Then head over to `android/app/src/main/AndroidManifest.xml` and add a `<meta-data>` tag of `android:name="expo.modules.notifications.default_notification_icon"` (or `android:name="expo.modules.notifications.large_notification_icon"` if you are changing the large icon) inside the `<application>` node referencing the custom icon with `@drawable/<notification_icon_name_you_used_in_step_1>`, like [here](https://github.com/expo/expo/blob/335e67a1a3a91598c02061f3318a881541d0d57a/apps/bare-expo/android/app/src/main/AndroidManifest.xml#L44-L46).
67  3. In the end your `AndroidManifest.xml` should look more or less like this:
68
69  ```xml
70  <manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
71    ...
72    <application ...>
73      ...
74      <meta-data
75        android:name="expo.modules.notifications.default_notification_icon"
76        android:resource="@drawable/ic_stat_notifications" /> <!-- @drawable/<insert_notification_icon_name> -->
77      ...
78    </application>
79  </manifest>
80  ```
81
82- **To customize the default color of the notification**:
83  1. you will need a color resource added to the native project's resources. Some information on how to do this can be found in [the official Android guide](https://developer.android.com/guide/topics/resources/more-resources#Color). The most simple and fail-safe instructions would be to:
84     1. ensure that there is a file under `android/app/src/main/res/values/colors.xml` (if there is none, create it)
85     2. ensure that it's a valid resources XML file (it should start with a `<?xml version="1.0" encoding="utf-8"?>` declaration and have a root node of `<resources>`)
86     3. inside the `<resources>` node add a `<color>` node with an arbitrary name (like `notification_icon_color`) containing the color in HEX format inside, like [here](https://github.com/expo/expo/blob/335e67a1a3a91598c02061f3318a881541d0d57a/apps/bare-expo/android/app/src/main/res/values/colors.xml#L3).
87     4. in the end your `colors.xml` should look more or less like this:
88        ```java
89        <?xml version="1.0" encoding="utf-8"?>
90        <resources>
91          <color name="notification_icon_color">#4630EB</color>
92        </resources>
93        ```
94  2. now, when the color is added to the project, we need to configure `expo-notifications` to use it when it displays a notification — head over to `android/app/src/main/AndroidManifest.xml` and add a `<meta-data>` tag of `android:name="expo.modules.notifications.default_notification_color"` inside the `<application>` node referencing the custom icon with `@color/<notification_icon_color_name>`, like [here](https://github.com/expo/expo/blob/335e67a1a3a91598c02061f3318a881541d0d57a/apps/bare-expo/android/app/src/main/AndroidManifest.xml#L47-L49).
95  3. In the end your `AndroidManifest.xml` should look more or less like this:
96  ```xml
97  <manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
98    ...
99    <application ...>
100      ...
101      <meta-data
102        android:name="expo.modules.notifications.default_notification_color"
103        android:resource="@color/notification_icon_color" /> <!-- @color/<insert_notification_icon_color_name> -->
104      ...
105    </application>
106  </manifest>
107  ```
108- An `AndroidManifest.xml` with both color (of name `notification_icon_color`) and an icon (of name `ic_stat_notifications`) name would look like this:
109  ```xml
110  <manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
111    <application ...>
112      ...
113      <meta-data
114        android:name="expo.modules.notifications.default_notification_icon"
115        android:resource="@drawable/ic_stat_notifications" />
116      <meta-data
117        android:name="expo.modules.notifications.default_notification_color"
118        android:resource="@color/notification_icon_color" />
119      ...
120    </application>
121  </manifest>
122  ```
123
124</p>
125</details>
126
127### Config plugin setup (optional)
128
129If you're using EAS Build, you can set your Android notification icon and color tint, add custom push notification sounds, and set your iOS notification environment using the expo-notifications config plugin ([what's a config plugin?](https://docs.expo.dev/config-plugins/introduction)). To setup, just add the config plugin to the plugins array of your `app.json` or `app.config.js` as shown below, then rebuild the app.
130
131```json
132{
133  "expo": {
134    ...
135    "plugins": [
136      [
137        "expo-notifications",
138        {
139          "icon": "./local/path/to/myNotificationIcon.png",
140          "color": "#ffffff",
141          "sounds": ["./local/path/to/mySound.wav", "./local/path/to/myOtherSound.wav"],
142          "mode": "production"
143        }
144      ]
145    ],
146  }
147}
148```
149
150<details><summary><strong>Expand to view property descriptions and default values</strong></summary> <p>
151
152- **icon**: Android only. Local path to an image to use as the icon for push notifications. 96x96 all-white png with transparency.
153- **color**: Android only. Tint color for the push notification image when it appears in the notification tray. Default: "#ffffff".
154- **sounds**: Array of local paths to sound files (.wav recommended) that can be used as custom notification sounds.
155- **mode**: iOS only. Environment of the app: either 'development' or 'production'. Default: 'development'.
156
157</p>
158</details>
159
160### Add your project's credentials to Expo server (optional)
161
162If you would like to send notifications with Expo servers, the servers will need to have a way to authenticate with APNS/FCM that they are authorized to send notifications on your behalf. To do this:
163
164- for Firebase Cloud Messaging, check out this guide: _[Uploading Server Credentials](https://docs.expo.dev/push-notifications/using-fcm/#uploading-server-credentials)_,
165- for APNS:
166  - run `expo credentials:manager` in the root of your application,
167  - if you've already uploaded a Push Notifications Key in another project and would like to reuse it in the current project, select _Use existing Push Notifications Key in current project_ (you may need to set `slug` and `ios.bundleIdentifier` fields in `app.json` so that the server knows to which `experienceId` and `bundleIdentifier` the key should be attributed),
168  - if you've never uploaded a Push Notifications Key or would like to add a new one
169    - select _Add new Push Notifications Key_
170    - if you'd like to let Expo handle the process, select _Let Expo handle the process_
171    - if you can't let Expo handle the process or you want to upload your own key, select _I want to upload my own file_
172      - provide a path to the P8 file you have downloaded from [developer.apple.com](https://developer.apple.com/) website.
173
174# Common gotchas / known issues
175
176### Fetching a push token takes a long time on iOS
177
178`getDevicePushTokenAsync` and `getExpoPushTokenAsync` can sometimes take a long time to resolve on iOS. This is outside of `expo-notifications`'s control, as stated in Apple's [“Troubleshooting Push Notifications” technical note](https://developer.apple.com/library/archive/technotes/tn2265/_index.html):
179
180> This is not necessarily an error condition. The system may not have Internet connectivity at all because it is out of range of any cell towers or Wi-Fi access points, or it may be in airplane mode. Instead of treating this as an error, your app should continue normally, disabling only that functionality that relies on push notifications.
181
182As mentioned, the most common reasons for this this are either an invalid Internet connection (fetching a push token requires an Internet connection to register the device with the service provider) or an invalid configuration of your App ID or Provisioning Profile.
183
184Here are a few ways people claim to have solved this problem, maybe one of these will help you solve it, too!
185
186<details><summary><strong>Read the Apple's <a href="https://developer.apple.com/library/archive/technotes/tn2265/_index.html">Technical Note on troubleshooting push notifications</a></strong></summary> <p>
187
188Go read the Apple's [Technical Note on troubleshooting push notifications](https://developer.apple.com/library/archive/technotes/tn2265/_index.html)! This the single most reliable source of information on this problem. To help you grasp what they're suggesting:
189
190- Make sure the device has a reliable connection to the Internet (try turning off Wi-Fi or switching to another network, and disabling firewall block on port 5223, as suggested in [this SO answer](https://stackoverflow.com/a/34332047/1123156)).
191- Make sure your app configuration is set properly for registering for push notifications (for bare workflow check out [this guide](https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/AddingCapabilities/AddingCapabilities.html), for managed workflow this is done automatically for you by `expo-cli`) as also suggested by [this StackOverflow answer](https://stackoverflow.com/a/10791240/1123156).
192- If you're in bare workflow you may want to try to debug this even further by logging persistent connection debug information as outlined by [this StackOverflow answer](https://stackoverflow.com/a/8036052/1123156).
193
194</p>
195</details>
196
197<details><summary><strong>Try again in a little while</strong></summary> <p>
198
199- APNS servers near the device may be down as indicated by [this forum thread](https://developer.apple.com/forums/thread/52224). Take a walk and try again later!
200- Try again in a few days time as suggested by [this GitHub comment](https://github.com/expo/expo/issues/10369#issuecomment-717872956).
201
202</p>
203</details>
204
205<details><summary><strong>Disable network sharing on your device</strong></summary> <p>
206
207You may need to disable network sharing as this may impact the registration as suggested by [this StackOverflow answer](https://stackoverflow.com/a/59156989/1123156).
208
209</p>
210</details>
211
212<details><summary><strong>Restart your device</strong></summary> <p>
213
214If you just changed the APNS servers where the app should be registering (by installing a TestFlight build over an Xcode build on the same device) you may need to restart your device as suggested by [this StackOverflow answer](https://stackoverflow.com/a/59864028/1123156).
215
216</p>
217</details>
218
219<details><summary><strong>Setup your device with a SIM card</strong></summary> <p>
220
221If the device you're experiencing this on hasn't been setup with a SIM card it looks like configuring it may help mitigate this bug as suggested by [this StackOverflow answer](https://stackoverflow.com/a/19432504/1123156).
222
223</p>
224</details>
225
226### Setting custom notification sounds
227
228Custom notification sounds are only supported when using [EAS Build](https://docs.expo.dev/build/introduction/), or in the bare workflow.
229
230To add custom push notification sounds to your app, add the `expo-notifications` plugin to your `app.json` file:
231
232```json
233{
234  "expo": {
235    "plugins": [
236      [
237        "expo-notifications",
238        {
239          "sounds": ["local/path/to/mySoundFile.wav"]
240        }
241      ]
242    ]
243  }
244}
245```
246
247After building your app, the array of files will be available for use in both [`NotificationContentInput`](#notificationcontentinput) and [`NotificationChannelInput`](#notificationchannelinput). You _only_ need to provide the base filename- here's an example using the config above:
248
249```ts
250await Notifications.setNotificationChannelAsync('new-emails', {
251  name: 'E-mail notifications',
252  sound: 'mySoundFile.wav', // Provide ONLY the base filename
253});
254
255await Notifications.scheduleNotificationAsync({
256  content: {
257    title: "You've got mail! ��",
258    sound: 'mySoundFile.wav', // Provide ONLY the base filename
259  },
260  trigger: {
261    seconds: 2,
262    channelId: 'new-emails',
263  },
264});
265```
266
267You can also manually add notification files to your Android and iOS projects if you prefer:
268
269<details><summary><strong>Manually adding notification sounds on Android</strong></summary> <p>
270
271On Androids 8.0+, playing a custom sound for a notification requires more than setting the `sound` property on the `NotificationContentInput`. You will _also_ need to configure the `NotificationChannel` with the appropriate `sound`, and use it when sending/scheduling the notification.
272
273For the example below to work, you would place your `email-sound.wav` file in `android/app/src/main/res/raw/`.
274
275```ts
276// Prepare the notification channel
277await Notifications.setNotificationChannelAsync('new-emails', {
278  name: 'E-mail notifications',
279  importance: Notifications.AndroidImportance.HIGH,
280  sound: 'email-sound.wav', // <- for Android 8.0+, see channelId property below
281});
282
283// Eg. schedule the notification
284await Notifications.scheduleNotificationAsync({
285  content: {
286    title: "You've got mail! ��",
287    body: 'Open the notification to read them all',
288    sound: 'email-sound.wav', // <- for Android below 8.0
289  },
290  trigger: {
291    seconds: 2,
292    channelId: 'new-emails', // <- for Android 8.0+, see definition above
293  },
294});
295```
296
297</p>
298</details>
299
300<details><summary><strong>Manually adding notification sounds on iOS</strong></summary> <p>
301
302On iOS, all that's needed is to place your sound file in your Xcode project, and then specify the sound file in your `NotificationContentInput`, like this:
303
304```ts
305await Notifications.scheduleNotificationAsync({
306  content: {
307    title: "You've got mail! ��",
308    body: 'Open the notification to read them all',
309    sound: 'notification.wav',
310  },
311  trigger: {
312    // ...
313  },
314});
315```
316
317</p>
318</details>
319
320# Contributing
321
322Contributions are very welcome! Please refer to guidelines described in the [contributing guide](https://github.com/expo/expo#contributing).
323
324---
325
326# API
327
328The following methods are exported by the `expo-notifications` module:
329
330- **fetching token for sending push notifications**
331  - [`getExpoPushTokenAsync`](#getexpopushtokenasyncoptions-expotokenoptions-expopushtoken) -- resolves with an Expo push token
332  - [`getDevicePushTokenAsync`](#getdevicepushtokenasync-devicepushtoken) -- resolves with a device push token
333  - [`addPushTokenListener`](#addpushtokenlistenerlistener-pushtokenlistener-subscription) -- adds a listener called when a new push token is issued
334  - [`removePushTokenSubscription`](#removepushtokensubscriptionsubscription-subscription-void) -- removes the listener registered with `addPushTokenListener`
335- **listening to notification events**
336  - [`useLastNotificationResponse`](#uselastnotificationresponse-undefined--notificationresponse--null) -- a React hook returning the most recently received notification response
337  - [`addNotificationReceivedListener`](#addnotificationreceivedlistenerlistener-event-notification--void-void) -- adds a listener called whenever a new notification is received
338  - [`addNotificationsDroppedListener`](#addnotificationsdroppedlistenerlistener---void-void) -- adds a listener called whenever some notifications have been dropped
339  - [`addNotificationResponseReceivedListener`](#addnotificationresponsereceivedlistenerlistener-event-notificationresponse--void-void) -- adds a listener called whenever user interacts with a notification
340  - [`removeNotificationSubscription`](#removenotificationsubscriptionsubscription-subscription-void) -- removes the listener registered with `addNotification*Listener()`
341- **handling incoming notifications when the app is in foreground**
342  - [`setNotificationHandler`](#setnotificationhandlerhandler-notificationhandler--null-void) -- sets the handler function responsible for deciding what to do with a notification that is received when the app is in foreground
343- **fetching permissions information**
344  - [`getPermissionsAsync`](#getpermissionsasync-promisenotificationpermissionsstatus) -- fetches current permission settings related to notifications
345  - [`requestPermissionsAsync`](#requestpermissionsasyncrequest-notificationpermissionsrequest-promisenotificationpermissionsstatus) -- requests permissions related to notifications
346- **managing application badge icon**
347  - [`getBadgeCountAsync`](#getbadgecountasync-promisenumber) -- fetches the application badge number value
348  - [`setBadgeCountAsync`](#setbadgecountasyncbadgecount-number-options-setbadgecountoptions-promiseboolean) -- sets the application badge number value
349- **scheduling notifications**
350  - [`getAllScheduledNotificationsAsync`](#getallschedulednotificationsasync-promisenotification) -- fetches information about all scheduled notifications
351  - [`presentNotificationAsync`](#presentnotificationasynccontent-notificationcontentinput-identifier-string-promisestring) -- schedules a notification for immediate trigger
352  - [`scheduleNotificationAsync`](#schedulenotificationasyncnotificationrequest-notificationrequestinput-promisestring) -- schedules a notification to be triggered in the future
353  - [`cancelScheduledNotificationAsync`](#cancelschedulednotificationasyncidentifier-string-promisevoid) -- removes a specific scheduled notification
354  - [`cancelAllScheduledNotificationsAsync`](#cancelallschedulednotificationsasync-promisevoid) -- removes all scheduled notifications
355  - [`getNextTriggerDateAsync`](#getnexttriggerdateasynctrigger-schedulablenotificationtriggerinput-promisenumber--null) -- calculates next trigger date for a notification trigger
356- **dismissing notifications**
357  - [`getPresentedNotificationsAsync`](#getpresentednotificationsasync-promisenotification) -- fetches information about all notifications present in the notification tray (Notification Center)
358  - [`dismissNotificationAsync`](#dismissnotificationasyncidentifier-string-promisevoid) -- removes a specific notification from the notification tray
359  - [`dismissAllNotificationsAsync`](#dismissallnotificationsasync-promisevoid) -- removes all notifications from the notification tray
360- **managing notification channels (Android-specific)**
361  - [`getNotificationChannelsAsync`](#getnotificationchannelsasync-promisenotificationchannel) -- fetches information about all known notification channels
362  - [`getNotificationChannelAsync`](#getnotificationchannelasyncidentifier-string-promisenotificationchannel--null) -- fetches information about a specific notification channel
363  - [`setNotificationChannelAsync`](#setnotificationchannelasyncidentifier-string-channel-notificationchannelinput-promisenotificationchannel--null) -- saves a notification channel configuration
364  - [`deleteNotificationChannelAsync`](#deletenotificationchannelasyncidentifier-string-promisevoid) -- deletes a notification channel
365  - [`getNotificationChannelGroupsAsync`](#getnotificationchannelgroupsasync-promisenotificationchannelgroup) -- fetches information about all known notification channel groups
366  - [`getNotificationChannelGroupAsync`](#getnotificationchannelgroupasyncidentifier-string-promisenotificationchannelgroup--null) -- fetches information about a specific notification channel group
367  - [`setNotificationChannelGroupAsync`](#setnotificationchannelgroupasyncidentifier-string-channel-notificationchannelgroupinput-promisenotificationchannelgroup--null) -- saves a notification channel group configuration
368  - [`deleteNotificationChannelGroupAsync`](#deletenotificationchannelgroupasyncidentifier-string-promisevoid) -- deletes a notification channel group
369  - **managing notification categories (interactive notifications)**
370  - [`setNotificationCategoryAsync`](#setnotificationcategoryasyncidentifier-string-actions-notificationaction-options-categoryoptions-promisenotificationcategory--null) -- creates a new notification category for interactive notifications
371  - [`getNotificationCategoriesAsync`](#getnotificationcategoriesasync-promisenotificationcategory) -- fetches information about all active notification categories
372  - [`deleteNotificationCategoryAsync`](#deletenotificationcategoryasyncidentifier-string-promiseboolean) -- deletes a notification category
373
374## Custom notification icon and colors (Android only)
375
376Setting a default icon and color for all of your app's notifications is almost too easy. In the managed workflow, just set your [`notification.icon`](https://docs.expo.dev/versions/latest/config/app/#notification) and [`notification.color`](https://docs.expo.dev/versions/latest/config/app/#notification) keys in `app.json`, and rebuild your app! In the bare workflow, you'll need to follow [these instructions](https://github.com/expo/expo/tree/main/packages/expo-notifications#configure-for-android).
377
378For your notification icon, make sure you follow [Google's design guidelines](https://material.io/design/iconography/product-icons.html#design-principles) (the icon must be all white with a transparent background) or else it may not be displayed as intended.
379
380In both the managed and bare workflow, you can also set a custom notification color _per-notification_ directly in your [`NotificationContentInput`](#notificationcontentinput) under the `color` attribute.
381
382## Android push notification payload specification
383
384When sending a push notification, put an object conforming to the following type as `data` of the notification:
385
386```ts
387export interface FirebaseData {
388  title?: string;
389  message?: string;
390  subtitle?: string;
391  sound?: boolean | string;
392  vibrate?: boolean | number[];
393  priority?: AndroidNotificationPriority;
394  badge?: number;
395}
396```
397
398## Fetching tokens for push notifications
399
400### `getExpoPushTokenAsync(options: ExpoTokenOptions): ExpoPushToken`
401
402Returns an Expo token that can be used to send a push notification to this device using Expo push notifications service. [Read more in the Push Notifications guide](https://docs.expo.dev/guides/push-notifications/).
403
404> **Note:** For Expo's backend to be able to send notifications to your app, you will need to provide it with push notification keys. This can be done using `expo-cli` (`expo credentials:manager`). [Read more in the “Upload notifications credentials” guide](https://docs.expo.dev/push-notifications/push-notifications-setup/#credentials).
405
406> **Note:** Especially on iOS, `Promise`s returned by this method may take longer periods of time to fulfill. For more information see [Fetching a push token takes a long time on iOS](#fetching-a-push-token-takes-a-long-time-on-ios).
407
408#### Arguments
409
410This function accepts an optional object allowing you to pass in configuration, consisting of fields (all are optional, but some may have to be defined if configuration cannot be inferred):
411
412- **experienceId (_string_)** -- The ID of the experience to which the token should be attributed. Defaults to [`Constants.manifest.id`](https://docs.expo.dev/versions/latest/sdk/constants/#constantsmanifest) exposed by `expo-constants`. In the bare workflow, you must provide a value which takes the shape `@username/projectSlug`, where `username` is the Expo account that the project is associated with, and `projectSlug` is your [`slug` from `app.json`](https://docs.expo.dev/versions/latest/config/app/#slug).
413- **devicePushToken ([_DevicePushToken_](#devicepushtoken))** -- The device push token with which to register at the backend. Defaults to a token fetched with [`getDevicePushTokenAsync()`](#getdevicepushtokenasync-devicepushtoken).
414- **applicationId (_string_)** -- The ID of the application to which the token should be attributed. Defaults to [`Application.applicationId`](https://docs.expo.dev/versions/latest/sdk/application/#applicationapplicationid) exposed by `expo-application`.
415- **development (_boolean_)** -- Makes sense only on iOS, where there are two push notification services: sandbox and production. This defines whether the push token is supposed to be used with the sandbox platform notification service. Defaults to [`Application.getIosPushNotificationServiceEnvironmentAsync()`](https://docs.expo.dev/versions/latest/sdk/application/#applicationgetiospushnotificationserviceenvironmentasync) exposed by `expo-application` or `false`. Most probably you won't need to customize that. You may want to customize that if you don't want to install `expo-application` and still use the sandbox APNS.
416
417#### Returns
418
419Returns a `Promise` that resolves to an object with the following fields:
420
421- **type (_string_)** -- Always `expo`.
422- **data (_string_)** -- The push token as a string.
423
424#### Examples
425
426##### Fetching the Expo push token and uploading it to a server
427
428```ts
429import Constants from 'expo-constants';
430import * as Notifications from 'expo-notifications';
431
432export async function registerForPushNotificationsAsync(userId: string) {
433  let experienceId = undefined;
434  if (!Constants.manifest) {
435    // Absence of the manifest means we're in bare workflow
436    experienceId = '@username/example';
437  }
438  const expoPushToken = await Notifications.getExpoPushTokenAsync({
439    experienceId,
440  });
441  await fetch('https://example.com/', {
442    method: 'POST',
443    headers: {
444      'Content-Type': 'application/json',
445    },
446    body: JSON.stringify({
447      userId,
448      expoPushToken,
449    }),
450  });
451}
452```
453
454### `getDevicePushTokenAsync(): DevicePushToken`
455
456Returns a native APNS, FCM token or a [`PushSubscription` data](https://developer.mozilla.org/en-US/docs/Web/API/PushSubscription) that can be used with another push notification service.
457
458> **Note:** Especially on iOS, `Promise`s returned by this method may take longer periods of time to fulfill. For more information see [Fetching a push token takes a long time on iOS](#fetching-a-push-token-takes-a-long-time-on-ios) section of the documentation.
459
460#### Returns
461
462A `Promise` that resolves to an object with the following fields:
463
464- **type (_string_)** -- Either `ios`, `android` or `web`.
465- **data (_string_ or _object_)** -- Either the push token as a string (for `type == "ios" | "android"`) or an object conforming to the type below (for `type == "web"`):
466  ```ts
467  {
468    endpoint: string;
469    keys: {
470      p256dh: string;
471      auth: string;
472    }
473  }
474  ```
475
476### `addPushTokenListener(listener: PushTokenListener): Subscription`
477
478In rare situations a push token may be changed by the push notification service while the app is running. When a token is rolled, the old one becomes invalid and sending notifications to it will fail. A push token listener will let you handle this situation gracefully by registering the new token with your backend right away.
479
480#### Arguments
481
482A single and required argument is a function accepting a push token as an argument. It will be called whenever the push token changes.
483
484#### Returns
485
486A [`Subscription`](#subscription) object representing the subscription of the provided listener.
487
488#### Examples
489
490Registering a push token listener using a React hook
491
492```tsx
493import React from 'react';
494import * as Notifications from 'expo-notifications';
495
496import { registerDevicePushTokenAsync } from '../api';
497
498export default function App() {
499  React.useEffect(() => {
500    const subscription = Notifications.addPushTokenListener(registerDevicePushTokenAsync);
501    return () => subscription.remove();
502  }, []);
503
504  return (
505    // Your app content
506  );
507}
508```
509
510### `removePushTokenSubscription(subscription: Subscription): void`
511
512Removes a push token subscription returned by a `addPushTokenListener` call.
513
514#### Arguments
515
516A single and required argument is a subscription returned by `addPushTokenListener`.
517
518## Listening to notification events
519
520Notification events include incoming notifications, interactions your users perform with notifications (this can be tapping on a notification, or interacting with it via [notification categories](#managing-notification-categories-interactive-notifications)), and rare occasions when your notifications may be dropped.
521
522A few different listeners are exposed, so we've provided a chart below which will hopefully help you understand when you can expect each one to be triggered:
523
524| User interacted with notification? | App state  | Listener(s) triggered                                                   |
525| :--------------------------------- | :--------: | ----------------------------------------------------------------------- |
526| false                              | Foreground | `NotificationReceivedListener`                                          |
527| false                              | Background | `BackgroundNotificationTask`                                            |
528| false                              |   Killed   | none                                                                    |
529| true                               | Foreground | `NotificationReceivedListener` & `NotificationResponseReceivedListener` |
530| true                               | Background | `NotificationResponseReceivedListener`                                  |
531| true                               |   Killed   | `NotificationResponseReceivedListener`                                  |
532
533> In the chart above, whenever `NotificationResponseReceivedListener` is triggered, the same would apply to the `useLastNotificationResponse` hook.
534
535### `useLastNotificationResponse(): undefined | NotificationResponse | null`
536
537A React hook always returning the notification response that was received most recently (a notification response designates an interaction with a notification, such as tapping on it).
538
539> If you don't want to use a hook, you can use `Notifications.getLastNotificationResponseAsync()` instead.
540
541#### Returns
542
543The hook may return one of these three types/values:
544
545- `undefined` -- until we're sure of what to return
546- `null` -- if no notification response has been received yet
547- a [`NotificationResponse`](#notificationresponse) object -- if a notification response was received
548
549#### Examples
550
551Responding to a notification tap by opening a URL that could be put into the notification's `data` (opening the URL is your responsibility and is not a part of the `expo-notifications` API):
552
553```ts
554import * as Notifications from 'expo-notifications';
555import { Linking } from 'react-native';
556
557export default function App() {
558  const lastNotificationResponse = Notifications.useLastNotificationResponse();
559  React.useEffect(() => {
560    if (
561      lastNotificationResponse &&
562      lastNotificationResponse.notification.request.content.data.url &&
563      lastNotificationResponse.actionIdentifier === Notifications.DEFAULT_ACTION_IDENTIFIER
564    ) {
565      Linking.openURL(lastNotificationResponse.notification.request.content.data.url);
566    }
567  }, [lastNotificationResponse]);
568
569  return (
570    /*
571     * your app
572     */
573  );
574}
575```
576
577### `addNotificationReceivedListener(listener: (event: Notification) => void): void`
578
579Listeners registered by this method will be called whenever a notification is received while the app is running.
580
581#### Arguments
582
583A single and required argument is a function accepting a notification ([`Notification`](#notification)) as an argument.
584
585#### Returns
586
587A [`Subscription`](#subscription) object representing the subscription of the provided listener.
588
589#### Examples
590
591Registering a notification listener using a React hook
592
593```tsx
594import React from 'react';
595import * as Notifications from 'expo-notifications';
596
597export default function App() {
598  React.useEffect(() => {
599    const subscription = Notifications.addNotificationReceivedListener(notification => {
600      console.log(notification);
601    });
602    return () => subscription.remove();
603  }, []);
604
605  return (
606    // Your app content
607  );
608}
609```
610
611### `addNotificationsDroppedListener(listener: () => void): void`
612
613Listeners registered by this method will be called whenever some notifications have been dropped by the server. Applicable only to Firebase Cloud Messaging which we use as notifications service on Android. It corresponds to `onDeletedMessages()` callback. [More information can be found in Firebase docs](https://firebase.google.com/docs/cloud-messaging/android/receive#override-ondeletedmessages).
614
615#### Arguments
616
617A single and required argument is a function–callback.
618
619#### Returns
620
621A [`Subscription`](#subscription) object representing the subscription of the provided listener.
622
623### `addNotificationResponseReceivedListener(listener: (event: NotificationResponse) => void): void`
624
625Listeners registered by this method will be called whenever a user interacts with a notification (eg. taps on it).
626
627#### Arguments
628
629A single and required argument is a function accepting notification response ([`NotificationResponse`](#notificationresponse)) as an argument.
630
631#### Returns
632
633A [`Subscription`](#subscription) object representing the subscription of the provided listener.
634
635#### Examples
636
637##### Registering a notification listener using a React hook
638
639```tsx
640import React from 'react';
641import { Linking } from 'react-native';
642import * as Notifications from 'expo-notifications';
643
644export default function Container() {
645  React.useEffect(() => {
646    const subscription = Notifications.addNotificationResponseReceivedListener(response => {
647      const url = response.notification.request.content.data.url;
648      Linking.openUrl(url);
649    });
650    return () => subscription.remove();
651  }, []);
652
653  return (
654    // Your app content
655  );
656}
657```
658
659##### Handling push notifications with React Navigation
660
661If you'd like to deep link to a specific screen in your app when you receive a push notification, you can configure React Navigation's [linking](https://reactnavigation.org/docs/navigation-container#linking) prop to do that:
662
663```tsx
664import React from 'react';
665import { Linking } from 'react-native';
666import * as Notifications from 'expo-notifications';
667import { NavigationContainer } from '@react-navigation/native';
668
669export default function App() {
670  return (
671    <NavigationContainer
672      linking={{
673        config: {
674          // Configuration for linking
675        },
676        subscribe(listener) {
677          const onReceiveURL = ({ url }: { url: string }) => listener(url);
678
679          // Listen to incoming links from deep linking
680          Linking.addEventListener('url', onReceiveURL);
681
682          // Listen to expo push notifications
683          const subscription = Notifications.addNotificationResponseReceivedListener((response) => {
684            const url = response.notification.request.content.data.url;
685
686            // Any custom logic to see whether the URL needs to be handled
687            //...
688
689            // Let React Navigation handle the URL
690            listener(url);
691          });
692
693          return () => {
694            // Clean up the event listeners
695            Linking.removeEventListener('url', onReceiveURL);
696            subscription.remove();
697          };
698        },
699      }}>
700      {/* Your app content */}
701    </NavigationContainer>
702  );
703}
704```
705
706See more details on [React Navigation documentation](https://reactnavigation.org/docs/deep-linking/#third-party-integrations).
707
708### `removeNotificationSubscription(subscription: Subscription): void`
709
710Removes a notification subscription returned by a `addNotification*Listener` call.
711
712#### Arguments
713
714A single and required argument is a subscription returned by `addNotification*Listener`.
715
716## Handling incoming notifications when the app is in foreground
717
718### `setNotificationHandler(handler: NotificationHandler | null): void`
719
720When a notification is received while the app is running, using this function you can set a callback that will decide whether the notification should be shown to the user or not.
721
722When a notification is received, `handleNotification` is called with the incoming notification as an argument. The function should respond with a behavior object within 3 seconds, otherwise the notification will be discarded. If the notification is handled successfully, `handleSuccess` is called with the identifier of the notification, otherwise (or on timeout) `handleError` will be called.
723
724The default behavior when the handler is not set or does not respond in time is not to show the notification.
725
726#### Arguments
727
728The function receives a single argument which should be either `null` (if you want to clear the handler) or an object of fields:
729
730- **handleNotification (_(Notification) => Promise<NotificationBehavior>_**) -- (required) a function accepting an incoming notification returning a `Promise` resolving to a behavior ([`NotificationBehavior`](#notificationbehavior)) applicable to the notification
731- **handleSuccess (_(notificationId: string) => void_)** -- (optional) a function called whenever an incoming notification is handled successfully
732- **handleError (_(error: Error) => void_)** -- (optional) a function called whenever handling of an incoming notification fails
733
734#### Examples
735
736Implementing a notification handler that always shows the notification when it is received
737
738```ts
739import * as Notifications from 'expo-notifications';
740
741Notifications.setNotificationHandler({
742  handleNotification: async () => ({
743    shouldShowAlert: true,
744    shouldPlaySound: false,
745    shouldSetBadge: false,
746  }),
747});
748```
749
750## Handling incoming notifications when the app is not in the foreground (not supported in Expo Go)
751
752> **Please note:** In order to handle notifications while the app is backgrounded on iOS, you _must_ add `remote-notification` to the `ios.infoPlist.UIBackgroundModes` key in your app.json, **and** add `"content-available": 1` to your push notification payload. Under normal circumstances, the “content-available” flag should launch your app if it isn’t running and wasn’t killed by the user, _however_, this is ultimately decided by the OS so it might not always happen.
753
754### `registerTaskAsync(taskName: string): void`
755
756When a notification is received while the app is backgrounded, using this function you can set a callback that will be run in response to that notification. Under the hood, this function is run using `expo-task-manager`. You **must** define the task _first_, with [`TaskManager.defineTask`](https://docs.expo.dev/versions/latest/sdk/task-manager/#taskmanagerdefinetasktaskname-task). Make sure you define it in the global scope.
757
758The `taskName` argument is the string you passed to `TaskManager.defineTask` as the "taskName". The callback function you define with `TaskManager.defineTask` will receive the following arguments:
759
760- **data**: The remote payload delivered by either FCM (Android) or APNs (iOS). [See here for details](#pushnotificationtrigger).
761- **error**: The error (if any) that occurred during execution of the task.
762- **executionInfo**: JSON object of additional info related to the task, including the `taskName`.
763
764#### Examples
765
766```ts
767import * as TaskManager from 'expo-task-manager';
768import * as Notifications from 'expo-notifications';
769
770const BACKGROUND_NOTIFICATION_TASK = 'BACKGROUND-NOTIFICATION-TASK';
771
772TaskManager.defineTask(BACKGROUND_NOTIFICATION_TASK, ({ data, error, executionInfo }) => {
773  console.log('Received a notification in the background!');
774  // Do something with the notification data
775});
776
777Notifications.registerTaskAsync(BACKGROUND_NOTIFICATION_TASK);
778```
779
780### `unregisterTaskAsync(taskName: string): void`
781
782Used to unregister tasks registered with `registerTaskAsync`.
783
784## Fetching information about notifications-related permissions
785
786### `getPermissionsAsync(): Promise<NotificationPermissionsStatus>`
787
788Calling this function checks current permissions settings related to notifications. It lets you verify whether the app is currently allowed to display alerts, play sounds, etc. There is no user-facing effect of calling this.
789
790#### Returns
791
792It returns a `Promise` resolving to an object representing permission settings (`NotificationPermissionsStatus`).
793
794#### Examples
795
796Check if the app is allowed to send any type of notifications (interrupting and non-interrupting–provisional on iOS)
797
798```ts
799import * as Notifications from 'expo-notifications';
800
801export async function allowsNotificationsAsync() {
802  const settings = await Notifications.getPermissionsAsync();
803  return (
804    settings.granted || settings.ios?.status === Notifications.IosAuthorizationStatus.PROVISIONAL
805  );
806}
807```
808
809### `requestPermissionsAsync(request?: NotificationPermissionsRequest): Promise<NotificationPermissionsStatus>`
810
811Prompts the user for notification permissions according to request. **Request defaults to asking the user to allow displaying alerts, setting badge count and playing sounds**.
812
813#### Arguments
814
815An optional object of conforming to the following interface:
816
817```ts
818{
819  android?: {};
820  ios?: {
821    allowAlert?: boolean;
822    allowBadge?: boolean;
823    allowSound?: boolean;
824    allowDisplayInCarPlay?: boolean;
825    allowCriticalAlerts?: boolean;
826    provideAppNotificationSettings?: boolean;
827    allowProvisional?: boolean;
828    allowAnnouncements?: boolean;
829  }
830}
831```
832
833Each option corresponds to a different native platform authorization option (a list of iOS options is available [here](https://developer.apple.com/documentation/usernotifications/unauthorizationoptions), on Android all available permissions are granted by default and if a user declines any permission an app can't prompt the user to change).
834
835#### Returns
836
837It returns a `Promise` resolving to an object representing permission settings (`NotificationPermissionsStatus`).
838
839#### Examples
840
841Prompts the user to allow the app to show alerts, play sounds, set badge count and let Siri read out messages through AirPods
842
843```ts
844import * as Notifications from 'expo-notifications';
845
846export function requestPermissionsAsync() {
847  return await Notifications.requestPermissionsAsync({
848    ios: {
849      allowAlert: true,
850      allowBadge: true,
851      allowSound: true,
852      allowAnnouncements: true,
853    },
854  });
855}
856```
857
858## Managing application badge icon
859
860### `getBadgeCountAsync(): Promise<number>`
861
862Fetches the number currently set as the badge of the app icon on device's home screen. A `0` value means that the badge is not displayed.
863
864> **Note:** Not all Android launchers support application badges. If the launcher does not support icon badges, the method will always resolve to `0`.
865
866#### Returns
867
868It returns a `Promise` resolving to a number representing current badge of the app icon.
869
870### `setBadgeCountAsync(badgeCount: number, options?: SetBadgeCountOptions): Promise<boolean>`
871
872Sets the badge of the app's icon to the specified number. Setting to `0` clears the badge.
873
874> **Note:** Not all Android launchers support application badges. If the launcher does not support icon badges, the method will resolve to `false`.
875
876#### Arguments
877
878The function accepts a number as the first argument. A value of `0` will clear the badge.
879
880As a second, optional argument you can pass in an object of options configuring behavior applied in Web environment. The object should be of format:
881
882```ts
883{
884  web?: badgin.Options
885}
886```
887
888where the type `badgin.Options` is an object described [in the `badgin`'s documentation](https://github.com/jaulz/badgin#options).
889
890#### Returns
891
892It returns a `Promise` resolving to a boolean representing whether setting of the badge succeeded.
893
894## Scheduling notifications
895
896### `getAllScheduledNotificationsAsync(): Promise<Notification[]>`
897
898Fetches information about all scheduled notifications.
899
900#### Returns
901
902It returns a `Promise` resolving to an array of objects conforming to the [`Notification`](#notification) interface.
903
904### `presentNotificationAsync(content: NotificationContentInput, identifier?: string): Promise<string>`
905
906Schedules a notification for immediate trigger.
907
908> **Note:** This method has been deprecated in favor of using an explicit `NotificationHandler` and the `scheduleNotificationAsync` method. More info may be found at https://expo.fyi/presenting-notifications-deprecated.
909
910#### Arguments
911
912The only argument to this function is a [`NotificationContentInput`](#notificationcontentinput).
913
914#### Returns
915
916It returns a `Promise` resolving with the notification's identifier once the notification is successfully scheduled for immediate display.
917
918#### Examples
919
920##### Presenting the notification to the user (deprecated way)
921
922```ts
923import * as Notifications from 'expo-notifications';
924
925Notifications.presentNotificationAsync({
926  title: 'Look at that notification',
927  body: "I'm so proud of myself!",
928});
929```
930
931##### Presenting the notification to the user (recommended way)
932
933```ts
934import * as Notifications from 'expo-notifications';
935
936// First, set the handler that will cause the notification
937// to show the alert
938
939Notifications.setNotificationHandler({
940  handleNotification: async () => ({
941    shouldShowAlert: true,
942    shouldPlaySound: false,
943    shouldSetBadge: false,
944  }),
945});
946
947// Second, call the method
948
949Notifications.scheduleNotificationAsync({
950  content: {
951    title: 'Look at that notification',
952    body: "I'm so proud of myself!",
953  },
954  trigger: null,
955});
956```
957
958### `scheduleNotificationAsync(notificationRequest: NotificationRequestInput): Promise<string>`
959
960Schedules a notification to be triggered in the future.
961
962> **Note:** Please note that this does not mean that the notification will be presented when it is triggered. For the notification to be presented you have to set a notification handler with [`setNotificationHandler`](#setnotificationhandlerhandler-notificationhandler--null-void) that will return an appropriate notification behavior. For more information see the example below.
963
964#### Arguments
965
966The one and only argument to this method is a [`NotificationRequestInput`](#notificationrequestinput) describing the notification to be triggered.
967
968#### Returns
969
970It returns a `Promise` resolving to a string --- a notification identifier you can later use to cancel the notification or to identify an incoming notification.
971
972#### Examples
973
974##### Scheduling the notification that will trigger once, in one minute from now
975
976```ts
977import * as Notifications from 'expo-notifications';
978
979Notifications.scheduleNotificationAsync({
980  content: {
981    title: "Time's up!",
982    body: 'Change sides!',
983  },
984  trigger: {
985    seconds: 60,
986  },
987});
988```
989
990##### Scheduling the notification that will trigger repeatedly, every 20 minutes
991
992```ts
993import * as Notifications from 'expo-notifications';
994
995Notifications.scheduleNotificationAsync({
996  content: {
997    title: 'Remember to drink water!,
998  },
999  trigger: {
1000    seconds: 60 * 20,
1001    repeats: true
1002  },
1003});
1004```
1005
1006##### Scheduling the notification that will trigger once, at the beginning of next hour
1007
1008```ts
1009import * as Notifications from 'expo-notifications';
1010
1011const trigger = new Date(Date.now() + 60 * 60 * 1000);
1012trigger.setMinutes(0);
1013trigger.setSeconds(0);
1014
1015Notifications.scheduleNotificationAsync({
1016  content: {
1017    title: 'Happy new hour!',
1018  },
1019  trigger,
1020});
1021```
1022
1023### `cancelScheduledNotificationAsync(identifier: string): Promise<void>`
1024
1025Cancels a single scheduled notification. The scheduled notification of given ID will not trigger.
1026
1027#### Arguments
1028
1029The notification identifier with which `scheduleNotificationAsync` resolved when the notification has been scheduled.
1030
1031#### Returns
1032
1033A `Promise` resolving once the scheduled notification is successfully cancelled or if there is no scheduled notification for given identifier.
1034
1035#### Examples
1036
1037##### Scheduling and then canceling the notification
1038
1039```ts
1040import * as Notifications from 'expo-notifications';
1041
1042async function scheduleAndCancel() {
1043  const identifier = await Notifications.scheduleNotificationAsync({
1044    content: {
1045      title: 'Hey!',
1046    },
1047    trigger: { seconds: 5, repeats: true },
1048  });
1049  await Notifications.cancelScheduledNotificationAsync(identifier);
1050}
1051```
1052
1053### `cancelAllScheduledNotificationsAsync(): Promise<void>`
1054
1055Cancels all scheduled notifications.
1056
1057#### Returns
1058
1059A `Promise` resolving once all the scheduled notifications are successfully cancelled or if there are no scheduled notifications.
1060
1061### `getNextTriggerDateAsync(trigger: SchedulableNotificationTriggerInput): Promise<number | null>`
1062
1063Allows you to check what will be the next trigger date for given notification trigger input.
1064
1065#### Arguments
1066
1067The schedulable notification trigger you would like to check next trigger date for (of type [`SchedulableNotificationTriggerInput`](#schedulablenotificationtriggerinput)).
1068
1069#### Returns
1070
1071If the return value is `null`, the notification won't be triggered. Otherwise, the return value is the Unix timestamp in milliseconds at which the notification will be triggered.
1072
1073#### Examples
1074
1075##### Calculating next trigger date for a notification trigger
1076
1077```ts
1078import * as Notifications from 'expo-notifications';
1079
1080async function logNextTriggerDate() {
1081  try {
1082    const nextTriggerDate = await Notifications.getNextTriggerDateAsync({
1083      hour: 9,
1084      minute: 0,
1085    });
1086    console.log(nextTriggerDate === null ? 'No next trigger date' : new Date(nextTriggerDate));
1087  } catch (e) {
1088    console.warn(`Couldn't have calculated next trigger date: ${e}`);
1089  }
1090}
1091```
1092
1093## Dismissing notifications
1094
1095### `getPresentedNotificationsAsync(): Promise<Notification[]>`
1096
1097Fetches information about all notifications present in the notification tray (Notification Center).
1098
1099> **Note:** This method is not supported on Android below 6.0 (API level 23) – on these devices it will resolve to an empty array.
1100
1101#### Returns
1102
1103A `Promise` resolving with a list of notifications ([`Notification`](#notification)) currently present in the notification tray (Notification Center).
1104
1105### `dismissNotificationAsync(identifier: string): Promise<void>`
1106
1107Removes notification displayed in the notification tray (Notification Center).
1108
1109#### Arguments
1110
1111The first and only argument to the function is the notification identifier, obtained either in `setNotificationHandler` or in the listener added with `addNotificationReceivedListener`.
1112
1113#### Returns
1114
1115Resolves once the request to dismiss the notification is successfully dispatched to the notifications manager.
1116
1117### `dismissAllNotificationsAsync(): Promise<void>`
1118
1119Removes all application's notifications displayed in the notification tray (Notification Center).
1120
1121#### Returns
1122
1123Resolves once the request to dismiss the notifications is successfully dispatched to the notifications manager.
1124
1125## Managing notification channels (Android-specific)
1126
1127> Starting in Android 8.0 (API level 26), all notifications must be assigned to a channel. For each channel, you can set the visual and auditory behavior that is applied to all notifications in that channel. Then, users can change these settings and decide which notification channels from your app should be intrusive or visible at all. [(source: developer.android.com)](https://developer.android.com/training/notify-user/channels)
1128
1129If you do not specify a notification channel, `expo-notifications` will create a fallback channel for you, named _Miscellaneous_. We encourage you to always ensure appropriate channels with informative names are set up for the application and to always send notifications to these channels.
1130
1131Calling these methods is a no-op for platforms that do not support this feature (iOS, Web and Android below version 8.0 (26)).
1132
1133### `getNotificationChannelsAsync(): Promise<NotificationChannel[]>`
1134
1135Fetches information about all known notification channels.
1136
1137#### Returns
1138
1139A `Promise` resolving to an array of channels. On platforms that do not support notification channels, it will always resolve to an empty array.
1140
1141### `getNotificationChannelAsync(identifier: string): Promise<NotificationChannel | null>`
1142
1143Fetches information about a single notification channel.
1144
1145#### Arguments
1146
1147The only argument to this method is the channel's identifier.
1148
1149#### Returns
1150
1151A `Promise` resolving to the channel object (of type [`NotificationChannel`](#notificationchannel)) or to `null` if there was no channel found for this identifier. On platforms that do not support notification channels, it will always resolve to `null`.
1152
1153### `setNotificationChannelAsync(identifier: string, channel: NotificationChannelInput): Promise<NotificationChannel | null>`
1154
1155Assigns the channel configuration to a channel of a specified name (creating it if need be). This method lets you assign given notification channel to a notification channel group.
1156
1157> **Note:** For some settings to be applied on all Android versions, it may be necessary to duplicate the configuration across both a single notification _and_ it's respective notification channel. For example, for a notification to play a custom sound on Android versions **below** 8.0, the custom notification sound has to be set on the notification (through the [`NotificationContentInput`](#notificationcontentinput)), and for the custom sound to play on Android versions **above** 8.0, the relevant notification channel must have the custom sound configured (through the [`NotificationChannelInput`](#notificationchannelinput)). For more information, see ["Setting custom notification sounds on Android"](#setting-custom-notification-sounds-on-android).
1158
1159#### Arguments
1160
1161First argument to the method is the channel identifier.
1162
1163Second argument is the channel's configuration of type [`NotificationChannelInput`](#notificationchannelinput)
1164
1165#### Returns
1166
1167A `Promise` resolving to the object (of type [`NotificationChannel`](#notificationchannel)) describing the modified channel or to `null` if the platform does not support notification channels.
1168
1169### `deleteNotificationChannelAsync(identifier: string): Promise<void>`
1170
1171Removes the notification channel.
1172
1173#### Arguments
1174
1175First and only argument to the method is the channel identifier.
1176
1177#### Returns
1178
1179A `Promise` resolving once the channel is removed (or if there was no channel for given identifier).
1180
1181### `getNotificationChannelGroupsAsync(): Promise<NotificationChannelGroup[]>`
1182
1183Fetches information about all known notification channel groups.
1184
1185#### Returns
1186
1187A `Promise` resolving to an array of channel groups. On platforms that do not support notification channel groups, it will always resolve to an empty array.
1188
1189### `getNotificationChannelGroupAsync(identifier: string): Promise<NotificationChannelGroup | null>`
1190
1191Fetches information about a single notification channel group.
1192
1193#### Arguments
1194
1195The only argument to this method is the channel group's identifier.
1196
1197#### Returns
1198
1199A `Promise` resolving to the channel group object (of type [`NotificationChannelGroup`](#notificationchannelgroup)) or to `null` if there was no channel group found for this identifier. On platforms that do not support notification channels, it will always resolve to `null`.
1200
1201### `setNotificationChannelGroupAsync(identifier: string, channel: NotificationChannelGroupInput): Promise<NotificationChannelGroup | null>`
1202
1203Assigns the channel group configuration to a channel group of a specified name (creating it if need be).
1204
1205#### Arguments
1206
1207First argument to the method is the channel group identifier.
1208
1209Second argument is the channel group's configuration of type [`NotificationChannelGroupInput`](#notificationchannelgroupinput)
1210
1211#### Returns
1212
1213A `Promise` resolving to the object (of type [`NotificationChannelGroup`](#notificationchannelgroup)) describing the modified channel group or to `null` if the platform does not support notification channels.
1214
1215### `deleteNotificationChannelGroupAsync(identifier: string): Promise<void>`
1216
1217Removes the notification channel group and all notification channels that belong to it.
1218
1219#### Arguments
1220
1221First and only argument to the method is the channel group identifier.
1222
1223#### Returns
1224
1225A `Promise` resolving once the channel group is removed (or if there was no channel group for given identifier).
1226
1227## Managing notification categories (interactive notifications)
1228
1229Notification categories allow you to create interactive push notifications, so that a user can respond directly to the incoming notification either via buttons or a text response. A category defines the set of actions a user can take, and then those actions are applied to a notification by specifying the `categoryIdentifier` in the [`NotificationContent`](#notificationcontent).
1230
1231On iOS, notification categories also allow you to customize your notifications further. With each category, not only can you set interactive actions a user can take, but you can also configure things like the placeholder text to display when the user disables notification previews for your app.
1232
1233Calling one of the following methods is a no-op on Web.
1234
1235### `setNotificationCategoryAsync(identifier: string, actions: NotificationAction[], options: CategoryOptions): Promise<NotificationCategory | null>`
1236
1237#### Arguments
1238
1239- `identifier`: A string to associate as the ID of this category. You will pass this string in as the `categoryIdentifier` in your [`NotificationContent`](#notificationcontent) to associate a notification with this category.
1240- `actions`: An array of [`NotificationAction`s](#notificationaction), which describe the actions associated with this category. Each of these actions takes the shape:
1241  - `identifier`: A unique string that identifies this action. If a user takes this action (i.e. selects this button in the system's Notification UI), your app will receive this `actionIdentifier` via the [`NotificationResponseReceivedListener`](#addnotificationresponsereceivedlistenerlistener-event-notificationresponse--void-void).
1242  - `buttonTitle`: The title of the button triggering this action.
1243  - `textInput`: **Optional** object which, if provided, will result in a button that prompts the user for a text response.
1244    - `submitButtonTitle`: (**iOS only**) A string which will be used as the title for the button used for submitting the text response.
1245    - `placeholder`: A string that serves as a placeholder until the user begins typing. Defaults to no placeholder string.
1246  - `options`: **Optional** object of additional configuration options.
1247    - `opensAppToForeground`: Boolean indicating whether triggering this action foregrounds the app (defaults to `true`). If `false` and your app is killed (not just backgrounded), [`NotificationResponseReceived` listeners](#addnotificationresponsereceivedlistenerlistener-event-notificationresponse--void-void) will not be triggered when a user selects this action.
1248    - `isAuthenticationRequired`: (**iOS only**) Boolean indicating whether triggering the action will require authentication from the user.
1249    - `isDestructive`: (**iOS only**) Boolean indicating whether the button title will be highlighted a different color (usually red). This usually signifies a destructive action such as deleting data.
1250- `options`: An optional object of additional configuration options for your category (**these are all iOS only**):
1251  - `previewPlaceholder`: Customizable placeholder for the notification preview text. This is shown if the user has disabled notification previews for the app. Defaults to the localized iOS system default placeholder (`Notification`).
1252  - `intentIdentifiers`: Array of [Intent Class Identifiers](https://developer.apple.com/documentation/sirikit/intent_class_identifiers). When a notification is delivered, the presence of an intent identifier lets the system know that the notification is potentially related to the handling of a request made through Siri. Defaults to an empty array.
1253  - `categorySummaryFormat`: A format string for the summary description used when the system groups the category’s notifications.
1254  - `customDismissAction`: A boolean indicating whether to send actions for handling when the notification is dismissed (the user must explicitly dismiss the notification interface- ignoring a notification or flicking away a notification banner does not trigger this action). Defaults to `false`.
1255  - `allowInCarPlay`: A boolean indicating whether to allow CarPlay to display notifications of this type. **Apps must be approved for CarPlay to make use of this feature.** Defaults to `false`.
1256  - `showTitle`: A boolean indicating whether to show the notification's title, even if the user has disabled notification previews for the app. Defaults to `false`.
1257  - `showSubtitle`: A boolean indicating whether to show the notification's subtitle, even if the user has disabled notification previews for the app. Defaults to `false`.
1258  - `allowAnnouncement`: A boolean indicating whether to allow notifications to be automatically read by Siri when the user is using AirPods. Defaults to `false`.
1259
1260#### Returns
1261
1262A `Promise` resolving to the category you just created.
1263
1264### `getNotificationCategoriesAsync(): Promise<NotificationCategory[]>`
1265
1266Fetches information about all known notification categories.
1267
1268#### Returns
1269
1270A `Promise` resolving to an array of `NotificationCategory`s. On platforms that do not support notification channels, it will always resolve to an empty array.
1271
1272### `deleteNotificationCategoryAsync(identifier: string): Promise<boolean>`
1273
1274Deletes the category associated with the provided identifier.
1275
1276#### Arguments
1277
1278Identifier initially provided to `setNotificationCategoryAsync` when creating the category.
1279
1280#### Returns
1281
1282A `Promise` resolving to `true` if the category was successfully deleted, or `false` if it was not. An example of when this method would return `false` is if you try to delete a category that doesn't exist.
1283
1284## Types
1285
1286### `DevicePushToken`
1287
1288In simple terms, an object of `type: Platform.OS` and `data: any`. The `data` type depends on the environment -- on a native device it will be a string, which you can then use to send notifications via Firebase Cloud Messaging (Android) or APNS (iOS); on web it will be a registration object (VAPID).
1289
1290```ts
1291export interface NativeDevicePushToken {
1292  type: 'ios' | 'android';
1293  data: string;
1294}
1295
1296export interface WebDevicePushToken {
1297  type: 'web';
1298  data: {
1299    endpoint: string;
1300    keys: {
1301      p256dh: string;
1302      auth: string;
1303    };
1304  };
1305}
1306
1307export type DevicePushToken = NativeDevicePushToken | WebDevicePushToken;
1308```
1309
1310### `PushTokenListener`
1311
1312A function accepting a device push token ([`DevicePushToken`](#devicepushtoken)) as an argument.
1313
1314> **Note:** You should not call `getDevicePushTokenAsync` inside this function, as it triggers the listener and may lead to an infinite loop.
1315
1316### `ExpoPushToken`
1317
1318Borrowing from `DevicePushToken` a little bit, it's an object of `type: 'expo'` and `data: string`. You can use the `data` value to send notifications via Expo Notifications service.
1319
1320```ts
1321export interface ExpoPushToken {
1322  type: 'expo';
1323  data: string;
1324}
1325```
1326
1327### `Subscription`
1328
1329A common-in-React-Native type to abstract an active subscription. Call `.remove()` to remove the subscription. You can then discard the object.
1330
1331```ts
1332export type Subscription = {
1333  remove: () => void;
1334};
1335```
1336
1337### `Notification`
1338
1339An object representing a single notification that has been triggered by some request ([`NotificationRequest`](#notificationrequest)) at some point in time.
1340
1341```ts
1342export interface Notification {
1343  date: number;
1344  request: NotificationRequest;
1345}
1346```
1347
1348### `NotificationRequest`
1349
1350An object representing a request to present a notification. It has content — how it's being represented — and a trigger — what triggers the notification. Many notifications ([`Notification`](#notification)) may be triggered with the same request (eg. a repeating notification).
1351
1352```ts
1353export interface NotificationRequest {
1354  identifier: string;
1355  content: NotificationContent;
1356  trigger: NotificationTrigger;
1357}
1358```
1359
1360### `NotificationContent`
1361
1362An object representing notification's content.
1363
1364```ts
1365export type NotificationContent = {
1366  // Notification title - the bold text displayed above the rest of the content
1367  title: string | null;
1368  // On iOS - subtitle - the bold text displayed between title and the rest of the content
1369  // On Android - subText - the display depends on the platform
1370  subtitle: string | null;
1371  // Notification body - the main content of the notification
1372  body: string | null;
1373  // Data associated with the notification, not displayed
1374  data: { [key: string]: unknown };
1375  // Application badge number associated with the notification
1376  badge: number | null;
1377  sound: 'default' | 'defaultCritical' | 'custom' | null;
1378} & (
1379  | {
1380      // iOS-specific additions
1381      // See https://developer.apple.com/documentation/usernotifications/unnotificationcontent?language=objc
1382      // for more information on specific fields.
1383      launchImageName: string | null;
1384      attachments: {
1385        identifier: string | null;
1386        url: string | null;
1387        type: string | null;
1388      }[];
1389      summaryArgument?: string | null;
1390      summaryArgumentCount?: number;
1391      categoryIdentifier: string | null;
1392      threadIdentifier: string | null;
1393      targetContentIdentifier?: string;
1394    }
1395  | {
1396      // Android-specific additions
1397      // See https://developer.android.com/reference/android/app/Notification.html#fields
1398      // for more information on specific fields.
1399      priority?: AndroidNotificationPriority;
1400      vibrationPattern?: number[];
1401      // Format: '#AARRGGBB'
1402      color?: string;
1403    }
1404);
1405```
1406
1407### `NotificationContentInput`
1408
1409An object representing notification content that you pass in to `presentNotificationAsync` or as a part of `NotificationRequestInput`.
1410
1411```ts
1412export interface NotificationContentInput {
1413  // Fields corresponding to NotificationContent
1414  title?: string;
1415  subtitle?: string;
1416  body?: string;
1417  data?: { [key: string]: unknown };
1418  badge?: number;
1419  sound?: boolean | string;
1420  // Android-specific fields
1421  // See https://developer.android.com/reference/android/app/Notification.html#fields
1422  // for more information on specific fields.
1423  vibrate?: boolean | number[];
1424  priority?: AndroidNotificationPriority;
1425  // Format: '#AARRGGBB', '#RRGGBB' or one of the named colors,
1426  // see https://developer.android.com/reference/kotlin/android/graphics/Color?hl=en
1427  color?: string;
1428  // If set to false, the notification will not be automatically dismissed when clicked.
1429  // The setting used when the value is not provided or is invalid is true (the notification
1430  // will be dismissed automatically). Corresponds directly to Android's `setAutoCancel`
1431  // behavior. In Firebase terms this property of a notification is called `sticky`.
1432  // See:
1433  // - https://developer.android.com/reference/android/app/Notification.Builder#setAutoCancel(boolean),
1434  // - https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#AndroidNotification.FIELDS.sticky
1435  autoDismiss?: boolean;
1436  // iOS-specific fields
1437  // See https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent?language=objc
1438  // for more information on specific fields.
1439  launchImageName?: string;
1440  attachments?: {
1441    url: string;
1442    identifier?: string;
1443
1444    typeHint?: string;
1445    hideThumbnail?: boolean;
1446    thumbnailClipArea?: { x: number; y: number; width: number; height: number };
1447    thumbnailTime?: number;
1448  }[];
1449}
1450```
1451
1452### `NotificationRequestInput`
1453
1454An object representing a notification request you can pass into `scheduleNotificationAsync`.
1455
1456```ts
1457export interface NotificationRequestInput {
1458  identifier?: string;
1459  content: NotificationContentInput;
1460  trigger: NotificationTriggerInput;
1461}
1462```
1463
1464### `AndroidNotificationPriority`
1465
1466An enum corresponding to values appropriate for Android's [`Notification#priority`](https://developer.android.com/reference/android/app/Notification#priority) field.
1467
1468```ts
1469export enum AndroidNotificationPriority {
1470  MIN = 'min',
1471  LOW = 'low',
1472  DEFAULT = 'default',
1473  HIGH = 'high',
1474  MAX = 'max',
1475}
1476```
1477
1478### `NotificationTrigger`
1479
1480A union type containing different triggers which may cause the notification to be delivered to the application.
1481
1482```ts
1483export type NotificationTrigger =
1484  | PushNotificationTrigger
1485  | CalendarNotificationTrigger
1486  | LocationNotificationTrigger
1487  | TimeIntervalNotificationTrigger
1488  | DailyNotificationTrigger
1489  | WeeklyNotificationTrigger
1490  | YearlyNotificationTrigger
1491  | UnknownNotificationTrigger;
1492```
1493
1494### `PushNotificationTrigger`
1495
1496An object representing a notification delivered by a push notification system.
1497
1498On Android under `remoteMessage` field a JS version of the Firebase `RemoteMessage` may be accessed. On iOS under `payload` you may find full contents of [`UNNotificationContent`'s](https://developer.apple.com/documentation/usernotifications/unnotificationcontent?language=objc) [`userInfo`](https://developer.apple.com/documentation/usernotifications/unnotificationcontent/1649869-userinfo?language=objc), i.e. [remote notification payload](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html)
1499
1500```ts
1501export type PushNotificationTrigger = { type: 'push' } & (
1502  | { payload: Record<string, unknown> } // iOS
1503  | { remoteMessage: FirebaseRemoteMessage } // Android
1504  | {}
1505);
1506```
1507
1508### `FirebaseRemoteMessage`
1509
1510A Firebase `RemoteMessage` that caused the notification to be delivered to the app.
1511
1512```ts
1513export interface FirebaseRemoteMessage {
1514  collapseKey: string | null;
1515  data: { [key: string]: string };
1516  from: string | null;
1517  messageId: string | null;
1518  messageType: string | null;
1519  originalPriority: number;
1520  priority: number;
1521  sentTime: number;
1522  to: string | null;
1523  ttl: number;
1524  notification: null | {
1525    body: string | null;
1526    bodyLocalizationArgs: string[] | null;
1527    bodyLocalizationKey: string | null;
1528    channelId: string | null;
1529    clickAction: string | null;
1530    color: string | null;
1531    usesDefaultLightSettings: boolean;
1532    usesDefaultSound: boolean;
1533    usesDefaultVibrateSettings: boolean;
1534    eventTime: number | null;
1535    icon: string | null;
1536    imageUrl: string | null;
1537    lightSettings: number[] | null;
1538    link: string | null;
1539    localOnly: boolean;
1540    notificationCount: number | null;
1541    notificationPriority: number | null;
1542    sound: string | null;
1543    sticky: boolean;
1544    tag: string | null;
1545    ticker: string | null;
1546    title: string | null;
1547    titleLocalizationArgs: string[] | null;
1548    titleLocalizationKey: string | null;
1549    vibrateTimings: number[] | null;
1550    visibility: number | null;
1551  };
1552}
1553```
1554
1555### `TimeIntervalNotificationTrigger`
1556
1557A trigger related to an elapsed time interval. May be repeating (see `repeats` field).
1558
1559```ts
1560export interface TimeIntervalNotificationTrigger {
1561  type: 'timeInterval';
1562  repeats: boolean;
1563  seconds: number;
1564}
1565```
1566
1567### `DailyNotificationTrigger`
1568
1569A trigger related to a daily notification. This is an Android-only type, the same functionality will be achieved on iOS with a `CalendarNotificationTrigger`.
1570
1571```ts
1572export interface DailyNotificationTrigger {
1573  type: 'daily';
1574  hour: number;
1575  minute: number;
1576}
1577```
1578
1579### `WeeklyNotificationTrigger`
1580
1581A trigger related to a weekly notification. This is an Android-only type, the same functionality will be achieved on iOS with a `CalendarNotificationTrigger`.
1582
1583```ts
1584export interface WeeklyNotificationTrigger {
1585  type: 'weekly';
1586  weekday: number;
1587  hour: number;
1588  minute: number;
1589}
1590```
1591
1592### `YearlyNotificationTrigger`
1593
1594A trigger related to a yearly notification. This is an Android-only type, the same functionality will be achieved on iOS with a `CalendarNotificationTrigger`.
1595
1596```ts
1597export interface YearlyNotificationTrigger {
1598  type: 'yearly';
1599  day: number;
1600  month: number;
1601  hour: number;
1602  minute: number;
1603}
1604```
1605
1606### `CalendarNotificationTrigger`
1607
1608A trigger related to a [`UNCalendarNotificationTrigger`](https://developer.apple.com/documentation/usernotifications/uncalendarnotificationtrigger?language=objc), available only on iOS.
1609
1610```ts
1611export interface CalendarNotificationTrigger {
1612  type: 'calendar';
1613  repeats: boolean;
1614  dateComponents: {
1615    era?: number;
1616    year?: number;
1617    month?: number;
1618    day?: number;
1619    hour?: number;
1620    minute?: number;
1621    second?: number;
1622    weekday?: number;
1623    weekdayOrdinal?: number;
1624    quarter?: number;
1625    weekOfMonth?: number;
1626    weekOfYear?: number;
1627    yearForWeekOfYear?: number;
1628    nanosecond?: number;
1629    isLeapMonth: boolean;
1630    timeZone?: string;
1631    calendar?: string;
1632  };
1633}
1634```
1635
1636### `LocationNotificationTrigger`
1637
1638A trigger related to a [`UNLocationNotificationTrigger`](https://developer.apple.com/documentation/usernotifications/unlocationnotificationtrigger?language=objc), available only on iOS.
1639
1640```ts
1641export interface LocationNotificationTrigger {
1642  type: 'location';
1643  repeats: boolean;
1644  region: CircularRegion | BeaconRegion;
1645}
1646
1647interface Region {
1648  type: string;
1649  identifier: string;
1650  notifyOnEntry: boolean;
1651  notifyOnExit: boolean;
1652}
1653
1654export interface CircularRegion extends Region {
1655  type: 'circular';
1656  radius: number;
1657  center: {
1658    latitude: number;
1659    longitude: number;
1660  };
1661}
1662
1663export interface BeaconRegion extends Region {
1664  type: 'beacon';
1665  notifyEntryStateOnDisplay: boolean;
1666  major: number | null;
1667  minor: number | null;
1668  uuid?: string;
1669  beaconIdentityConstraint?: {
1670    uuid: string;
1671    major: number | null;
1672    minor: number | null;
1673  };
1674}
1675```
1676
1677### `UnknownNotificationTrigger`
1678
1679Represents a notification trigger that is unknown to `expo-notifications` and that it didn't know how to serialize for JS.
1680
1681```ts
1682export interface UnknownNotificationTrigger {
1683  type: 'unknown';
1684}
1685```
1686
1687### `NotificationTriggerInput`
1688
1689A type representing possible triggers with which you can schedule notifications. A `null` trigger means that the notification should be scheduled for delivery immediately.
1690
1691```ts
1692export type NotificationTriggerInput =
1693  | null
1694  | ChannelAwareTriggerInput
1695  | SchedulableNotificationTriggerInput;
1696```
1697
1698### `SchedulableNotificationTriggerInput`
1699
1700A type representing time-based, schedulable triggers. For these triggers you can check the next trigger date with [`getNextTriggerDateAsync`](#getnexttriggerdateasynctrigger-schedulablenotificationtriggerinput-promisenumber--null).
1701
1702```ts
1703export type SchedulableNotificationTriggerInput =
1704  | DateTriggerInput
1705  | TimeIntervalTriggerInput
1706  | DailyTriggerInput
1707  | WeeklyTriggerInput
1708  | YearlyTriggerInput
1709  | CalendarTriggerInput;
1710```
1711
1712### `ChannelAwareTriggerInput`
1713
1714A trigger that will cause the notification to be delivered immediately.
1715
1716```ts
1717export type ChannelAwareTriggerInput = {
1718  channelId: string;
1719};
1720```
1721
1722### `DateTriggerInput`
1723
1724A trigger that will cause the notification to be delivered once at the specified `Date`. If you pass in a `number` it will be interpreted as a UNIX timestamp.
1725
1726```ts
1727export type DateTriggerInput = Date | number | { channelId?: string; date: Date | number };
1728```
1729
1730### `TimeIntervalTriggerInput`
1731
1732A trigger that will cause the notification to be delivered once or many times (depends on the `repeats` field) after `seconds` time elapse.
1733
1734```ts
1735export interface TimeIntervalTriggerInput {
1736  channelId?: string;
1737  repeats?: boolean;
1738  seconds: number;
1739}
1740```
1741
1742### `DailyTriggerInput`
1743
1744A trigger that will cause the notification to be delivered once per day.
1745
1746```ts
1747export interface DailyTriggerInput {
1748  channelId?: string;
1749  hour: number;
1750  minute: number;
1751  repeats: true;
1752}
1753```
1754
1755### `WeeklyTriggerInput`
1756
1757A trigger that will cause the notification to be delivered once every week.
1758
1759> **Note:** Weekdays are specified with a number from 1 through 7, with 1 indicating Sunday.
1760
1761```ts
1762export interface WeeklyTriggerInput {
1763  channelId?: string;
1764  weekday: number;
1765  hour: number;
1766  minute: number;
1767  repeats: true;
1768}
1769```
1770
1771### `YearlyTriggerInput`
1772
1773A trigger that will cause the notification to be delivered once every year.
1774
1775> **Note:** all properties are specified in JavaScript Date's ranges.
1776
1777```ts
1778export interface YearlyTriggerInput {
1779  channelId?: string;
1780  day: number;
1781  month: number;
1782  hour: number;
1783  minute: number;
1784  repeats: true;
1785}
1786```
1787
1788### `CalendarTriggerInput`
1789
1790A trigger that will cause the notification to be delivered once or many times when the date components match the specified values. Corresponds to native [`UNCalendarNotificationTrigger`](https://developer.apple.com/documentation/usernotifications/uncalendarnotificationtrigger?language=objc).
1791
1792> **Note:** This type of trigger is only available on iOS.
1793
1794```ts
1795export interface CalendarTriggerInput {
1796  channelId?: string;
1797  repeats?: boolean;
1798  timezone?: string;
1799
1800  year?: number;
1801  month?: number;
1802  weekday?: number;
1803  weekOfMonth?: number;
1804  weekOfYear?: number;
1805  weekdayOrdinal?: number;
1806  day?: number;
1807
1808  hour?: number;
1809  minute?: number;
1810  second?: number;
1811}
1812```
1813
1814### `NotificationResponse`
1815
1816An object representing user's interaction with the notification.
1817
1818> **Note:** If the user taps on a notification `actionIdentifier` will be equal to `Notifications.DEFAULT_ACTION_IDENTIFIER`.
1819
1820```ts
1821export interface NotificationResponse {
1822  notification: Notification;
1823  actionIdentifier: string;
1824  userText?: string;
1825}
1826```
1827
1828### `NotificationBehavior`
1829
1830An object representing behavior that should be applied to the incoming notification.
1831
1832```ts
1833export interface NotificationBehavior {
1834  shouldShowAlert: boolean;
1835  shouldPlaySound: boolean;
1836  shouldSetBadge: boolean;
1837  priority?: AndroidNotificationPriority;
1838}
1839```
1840
1841> On Android, setting `shouldPlaySound: false` will result in the drop-down notification alert **not** showing, no matter what the priority is. This setting will also override any channel-specific sounds you may have configured.
1842
1843### `NotificationChannel`
1844
1845An object representing a notification channel (feature available only on Android).
1846
1847```ts
1848export enum AndroidNotificationVisibility {
1849  UNKNOWN,
1850  PUBLIC,
1851  PRIVATE,
1852  SECRET,
1853}
1854
1855export enum AndroidAudioContentType {
1856  UNKNOWN,
1857  SPEECH,
1858  MUSIC,
1859  MOVIE,
1860  SONIFICATION,
1861}
1862
1863export enum AndroidImportance {
1864  UNKNOWN,
1865  UNSPECIFIED,
1866  NONE,
1867  MIN,
1868  LOW,
1869  DEFAULT,
1870  HIGH,
1871  MAX,
1872}
1873
1874export enum AndroidAudioUsage {
1875  UNKNOWN,
1876  MEDIA,
1877  VOICE_COMMUNICATION,
1878  VOICE_COMMUNICATION_SIGNALLING,
1879  ALARM,
1880  NOTIFICATION,
1881  NOTIFICATION_RINGTONE,
1882  NOTIFICATION_COMMUNICATION_REQUEST,
1883  NOTIFICATION_COMMUNICATION_INSTANT,
1884  NOTIFICATION_COMMUNICATION_DELAYED,
1885  NOTIFICATION_EVENT,
1886  ASSISTANCE_ACCESSIBILITY,
1887  ASSISTANCE_NAVIGATION_GUIDANCE,
1888  ASSISTANCE_SONIFICATION,
1889  GAME,
1890}
1891
1892export interface AudioAttributes {
1893  usage: AndroidAudioUsage;
1894  contentType: AndroidAudioContentType;
1895  flags: {
1896    enforceAudibility: boolean;
1897    requestHardwareAudioVideoSynchronization: boolean;
1898  };
1899}
1900
1901export interface NotificationChannel {
1902  id: string;
1903  name: string | null;
1904  importance: AndroidImportance;
1905  bypassDnd: boolean;
1906  description: string | null;
1907  groupId?: string | null;
1908  lightColor: string;
1909  lockscreenVisibility: AndroidNotificationVisibility;
1910  showBadge: boolean;
1911  sound: 'default' | 'custom' | null;
1912  audioAttributes: AudioAttributes;
1913  vibrationPattern: number[] | null;
1914  enableLights: boolean;
1915  enableVibrate: boolean;
1916}
1917```
1918
1919### `NotificationChannelInput`
1920
1921An object representing a notification channel to be set.
1922
1923```ts
1924export interface NotificationChannelInput {
1925  name: string | null;
1926  importance: AndroidImportance;
1927  // Optional attributes
1928  bypassDnd?: boolean;
1929  description?: string | null;
1930  groupId?: string | null;
1931  lightColor?: string;
1932  lockscreenVisibility?: AndroidNotificationVisibility;
1933  showBadge?: boolean;
1934  sound?: string | null;
1935  audioAttributes?: Partial<AudioAttributes>;
1936  vibrationPattern?: number[] | null;
1937  enableLights?: boolean;
1938  enableVibrate?: boolean;
1939}
1940```
1941
1942### `NotificationChannelGroup`
1943
1944An object representing a notification channel group (feature available only on Android).
1945
1946```ts
1947export interface NotificationChannelGroup {
1948  id: string;
1949  name: string | null;
1950  description?: string | null;
1951  isBlocked?: boolean;
1952  channels: NotificationChannel[];
1953}
1954```
1955
1956### `NotificationChannelGroupInput`
1957
1958An object representing a notification channel group to be set.
1959
1960```ts
1961export interface NotificationChannelGroupInput {
1962  name: string | null;
1963  description?: string | null;
1964}
1965```
1966
1967### `NotificationCategory`
1968
1969```ts
1970export interface NotificationCategory {
1971  identifier: string;
1972  actions: NotificationAction[];
1973  options: {
1974    // These options are ALL iOS-only
1975    previewPlaceholder?: string;
1976    intentIdentifiers?: string[];
1977    categorySummaryFormat?: string;
1978    customDismissAction?: boolean;
1979    allowInCarPlay?: boolean;
1980    showTitle?: boolean;
1981    showSubtitle?: boolean;
1982    allowAnnouncement?: boolean;
1983  };
1984}
1985```
1986
1987### `NotificationAction`
1988
1989```ts
1990export interface NotificationAction {
1991  identifier: string;
1992  buttonTitle: string;
1993  textInput?: {
1994    submitButtonTitle: string;
1995    placeholder: string;
1996  };
1997  options: {
1998    isDestructive?: boolean;
1999    isAuthenticationRequired?: boolean;
2000    opensAppToForeground?: boolean;
2001  };
2002}
2003```
2004