<commit_before># expo-notifications

Provides an API to fetch push notification tokens and to present, schedule, receive and respond to notifications.

## Features

- 📣 schedule a one-off notification for a specific date, or some time from now,
- 🔁 schedule a notification repeating in some time interval (or a calendar date match on iOS),
- 1️⃣ get and set application badge icon number,
- 📲 fetch a native device push token so you can send push notifications with FCM and APNS,
- 😎 fetch an Expo push token so you can send push notifications with Expo,
- 📬 listen to incoming notifications in the foreground and background,
- 👆 listen to interactions with notifications (tapping or dismissing),
- 🎛 handle notifications when the app is in foreground,
- 🔕 imperatively dismiss notifications from Notification Center/tray,
- 🗂 create, update, delete Android notification channels,
- 🎨 set custom icon and color for notifications on Android.

# Installation in managed Expo projects

Please refer to the [installation instructions in the Expo documentation](https://docs.expo.io/versions/latest/sdk/notifications/#installation).

# Installation in bare React Native projects

For bare React Native projects, you must ensure that you have [installed and configured the `react-native-unimodules` package](https://github.com/expo/expo/tree/master/packages/react-native-unimodules) before continuing.

### Add the package to your npm dependencies

```
expo install expo-notifications
```

### Configure for iOS

Run `npx pod-install` after installing the npm package.

In order to be able to receive push notifications on the device:

- open Xcode workspace from your `ios` folder
- select your project from the _Navigator_ pane
- switch to _Signing & Capabilities_ tab
- ensure that the _Push notifications_ capability is present (if it's not, click the "+ Capability" button and add the capability to the project).

### Configure for Android

In 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.io/guides/setup-native-firebase/#bare-workflow-setup).

This 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.

### Optional setup for notification icon, tint color, and custom sounds

If you're using EAS Build or the bare workflow, 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?](http://docs.expo.io/guides/config-plugins/)). To setup, just add the config plugin to the `plugins` array of your `app.json` or `app.config.js`:

```json
{
  "expo": {
    ...
    "plugins": [
      [
        "expo-notifications",
        {
          "icon": "./local/path/to/myNotificationIcon.png",
          "color": "#ffffff",
          "sounds": ["./local/path/to/mySound.wav", "./local/path/to/myOtherSound.wav"],
          "mode": "production"
        }
      ]
    ],
  }
}
```

<details><summary><strong>Expand to view property descriptions and default values</strong></summary> <p>

- **icon**: Android only. Local path to an image to use as the icon for push notifications. 96x96 all-white png with transparency.
- **color**: Android only. Tint color for the push notification image when it appears in the notification tray. Default: "#ffffff".
- **sounds**: Array of local paths to sound files (.wav recommended) that can be used as custom notification sounds.
- **mode**: iOS only. Environment of the app: either 'development' or 'production'. Default: 'development'.

</p>
</details>

Then rebuild the app. If you're using the bare workflow, make sure to run `expo prebuild` first (this will apply the config plugin using [prebuilding](https://expo.fyi/prebuilding)).

### Add your project's credentials to Expo server (optional)

If 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:

- for Firebase Cloud Messaging, check out this guide: _[Uploading Server Credentials](https://docs.expo.io/push-notifications/using-fcm/#uploading-server-credentials)_,
- for APNS:
  - run `expo credentials:manager` in the root of your application,
  - 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),
  - if you've never uploaded a Push Notifications Key or would like to add a new one
    - select _Add new Push Notifications Key_
    - if you'd like to let Expo handle the process, select _Let Expo handle the process_
    - 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_
      - provide a path to the P8 file you have downloaded from [developer.apple.com](https://developer.apple.com/) website.

# Common gotchas / known issues

### Fetching a push token takes a long time on iOS

`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):

> 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.

As 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.
<commit_msg>[notifications] update readme w/ notification icon info<commit_after># expo-notifications

Provides an API to fetch push notification tokens and to present, schedule, receive and respond to notifications.

## Features

- 📣 schedule a one-off notification for a specific date, or some time from now,
- 🔁 schedule a notification repeating in some time interval (or a calendar date match on iOS),
- 1️⃣ get and set application badge icon number,
- 📲 fetch a native device push token so you can send push notifications with FCM and APNS,
- 😎 fetch an Expo push token so you can send push notifications with Expo,
- 📬 listen to incoming notifications in the foreground and background,
- 👆 listen to interactions with notifications (tapping or dismissing),
- 🎛 handle notifications when the app is in foreground,
- 🔕 imperatively dismiss notifications from Notification Center/tray,
- 🗂 create, update, delete Android notification channels,
- 🎨 set custom icon and color for notifications on Android.

# Installation in managed Expo projects

Please refer to the [installation instructions in the Expo documentation](https://docs.expo.io/versions/latest/sdk/notifications/#installation).

# Installation in bare React Native projects

For bare React Native projects, you must ensure that you have [installed and configured the `react-native-unimodules` package](https://github.com/expo/expo/tree/master/packages/react-native-unimodules) before continuing.

### Add the package to your npm dependencies

```
expo install expo-notifications
```

### Configure for iOS

Run `npx pod-install` after installing the npm package.

In order to be able to receive push notifications on the device:

- open Xcode workspace from your `ios` folder
- select your project from the _Navigator_ pane
- switch to _Signing & Capabilities_ tab
- ensure that the _Push notifications_ capability is present (if it's not, click the "+ Capability" button and add the capability to the project).

### Configure for Android

In 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.io/guides/setup-native-firebase/#bare-workflow-setup).

This 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.

<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>

- **To customize the icon**:

  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.

  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!
  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).
  3. In the end your `AndroidManifest.xml` should look more or less like this:

  ```xml
  <manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
    ...
    <application ...>
      ...
      <meta-data
        android:name="expo.modules.notifications.default_notification_icon"
        android:resource="@drawable/ic_stat_notifications" /> <!-- @drawable/<insert_notification_icon_name> -->
      ...
    </application>
  </manifest>
  ```

- **To customize the default color of the notification**:
  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:
     1. ensure that there is a file under `android/app/src/main/res/values/colors.xml` (if there is none, create it)
     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>`)
     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).
     4. in the end your `colors.xml` should look more or less like this:
        ```java
        <?xml version="1.0" encoding="utf-8"?>
        <resources>
          <color name="notification_icon_color">#4630EB</color>
        </resources>
        ```
  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).
  3. In the end your `AndroidManifest.xml` should look more or less like this:
  ```xml
  <manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
    ...
    <application ...>
      ...
      <meta-data
        android:name="expo.modules.notifications.default_notification_color"
        android:resource="@color/notification_icon_color" /> <!-- @color/<insert_notification_icon_color_name> -->
      ...
    </application>
  </manifest>
  ```
- An `AndroidManifest.xml` with both color (of name `notification_icon_color`) and an icon (of name `ic_stat_notifications`) name would look like this:
  ```xml
  <manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
    <application ...>
      ...
      <meta-data
        android:name="expo.modules.notifications.default_notification_icon"
        android:resource="@drawable/ic_stat_notifications" />
      <meta-data
        android:name="expo.modules.notifications.default_notification_color"
        android:resource="@color/notification_icon_color" />
      ...
    </application>
  </manifest>
  ```

</p>
</details>

### Config plugin setup (optional)

If 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?](http://docs.expo.io/guides/config-plugins/)). 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.

```json
{
  "expo": {
    ...
    "plugins": [
      [
        "expo-notifications",
        {
          "icon": "./local/path/to/myNotificationIcon.png",
          "color": "#ffffff",
          "sounds": ["./local/path/to/mySound.wav", "./local/path/to/myOtherSound.wav"],
          "mode": "production"
        }
      ]
    ],
  }
}
```

<details><summary><strong>Expand to view property descriptions and default values</strong></summary> <p>

- **icon**: Android only. Local path to an image to use as the icon for push notifications. 96x96 all-white png with transparency.
- **color**: Android only. Tint color for the push notification image when it appears in the notification tray. Default: "#ffffff".
- **sounds**: Array of local paths to sound files (.wav recommended) that can be used as custom notification sounds.
- **mode**: iOS only. Environment of the app: either 'development' or 'production'. Default: 'development'.

</p>
</details>

### Add your project's credentials to Expo server (optional)

If 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:

- for Firebase Cloud Messaging, check out this guide: _[Uploading Server Credentials](https://docs.expo.io/push-notifications/using-fcm/#uploading-server-credentials)_,
- for APNS:
  - run `expo credentials:manager` in the root of your application,
  - 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),
  - if you've never uploaded a Push Notifications Key or would like to add a new one
    - select _Add new Push Notifications Key_
    - if you'd like to let Expo handle the process, select _Let Expo handle the process_
    - 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_
      - provide a path to the P8 file you have downloaded from [developer.apple.com](https://developer.apple.com/) website.

# Common gotchas / known issues

### Fetching a push token takes a long time on iOS

`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):

> 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.

As 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.

{'fraction_non_alphanumeric': 0.08870641299947955, 'fraction_numerical': 0.008095761290695657, 'mean_word_length': 4.131750741839762, 'pattern_counts': {'":': 12, '<': 62, '<?xml version=': 2, '>': 64, 'https://': 19, 'lorem ipsum': 0, 'www.': 0, 'xml': 18}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3853218', 'n_tokens_mistral': 4869, 'n_tokens_neox': 4575, 'n_words': 2065}