Вступление

На написание данной статьи меня натолкнул факт отсутствия в русскоязычном сегменте интрнета какого либо примера по настройке пуш уведомлений с использованием лишь инструментов которые предоставляет Expo Go.

Несомненно, примеры по настройки на чистом React Native либо с использованием команды eject в случае с Expo Go (что в целом не особо меняет ситуацию от чистого React Naitve) есть =).

И да, скажу сразу что в данной статье я не буду рассматривать как настроить какие-то специфичные вещи ввиде настройки звуков для уведомлений, либо же еще какой-нибудь несусветной дряни, тупо настроим шо бы работало так сказать.

Клиент

Настройка APNs сервиса

Немного об APNs

Служба push-уведомлений Apple — сервис, созданный Apple для отправки уведомлений от сторонних приложений на устройства Apple.

Есть интересная статья по теме сервиса.

Как бы это странно не звучало, но при использовании EAS сервисов делать тут нам практически ничего не нужно будет.

Разве что при первом деплое приложения, EAS предложит настроить ключи для пуш уведомлений (конечно же после того как вы авторизуетесь в Apple Developer account), но там от вас требуются только жать Enter =).

Настройка FCM сервиса

До начала настройки FCM(Firebase Cloud Messaging) у вас уже должно быть развернуто и сконфигурировано приложение.

А точнее нам нужно добыть (если нет, прописать) из app.json поле android.package

Дальше авторизовываемся в firebase, если проект еше не создан, необходимо создать, далее необходимо добавить наше android приложение.

Добавить его можно кликнув на значек android на главном экране.

Если не обнаружили тогда переходим в настройки и точно такую же панель с доступными платформами можно найти там.

При добавление самое главное нужно заполнить поле Android package name в в соответствие с полем android.package в app.json.

Далее в завершении, скачиваем файл google-servces.json и кидаем его в наш проект. После, открываем app.json и в поле android.googleServicesFile прописываем путь до файла относительно нашего конфиг файла.

После проделанных манипуляций нам остается добавить лишь Cloud Messaging API Server Key, заходим в Project settings > Cloud Messaging и в блоке Cloud Messaging API можно найти поле Server Key копируем его, он нам сейчас пригодится.

Если поле не было обнаружено то в google cloud console просто нужно активировать Cloud Messaging для своего проекта.

Перед выполнениям следующего действия, убедись что зарегистрирован на expo.dev и авторизован в CLI.

Заходим в терминал, пишем команду $ expo push:android:upload --api-key <your-token-here> и сохраняем наш апи ключ, с помощью которого EAS сможет использовать его для отправки пуш уведомлений.

Заходим в раздел Credentials на сайте expo и убеждаемся, что ключ успешно добавлен.

Если все хорошо, то можем переходить к следующему блоку.

Работа с приложением

Для начала нам нужно установить пакет expo-notifications для взаимодействия с уведомлениями в приложении, и expo-device для определения устройство это или симулятор/эмулятор:

$ npm i expo-notifications expo-device

Получение токена

Для отправки пуш уведомлений, нам нужно получить токен нашего приложения написанного с использованием ExpoGo.

Создадим методы для работы с библиотекой:

  1. Получение разрешения на возможность получать уведомления и запроса токена в случае успеха.

  2. Событие обработки при нажатие на уведомление.

Метод первый. Запрос прав и получение токена

async function registerForPushNotificationsAsync()
{
    if (Device.isDevice) {
        const {status: existingStatus} = 
              await Notifications.getPermissionsAsync();
        let finalStatus = existingStatus;

        if (existingStatus !== "granted") {
            const {status} = await Notifications.requestPermissionsAsync();
            finalStatus = status;
        }

        if (finalStatus !== "granted") {
            alert("Failed to get push token for push notification!");
            return;
        }

        const token = (await Notifications.getExpoPushTokenAsync()).data;

        // TODO Используем полученный токен
    } else {
        alert("Must use physical device for Push Notifications");
    }

    if (Platform.OS === "android") {
        Notifications.setNotificationChannelAsync("default", {
            name: "default",
            importance: Notifications.AndroidImportance.MAX,
            vibrationPattern: [0, 250, 250, 250],
            lightColor: "#FF231F7C",
        });
    }
}

Разберем что же тут собственно просиходит.


Проверка на то запушен метод на устройстве или на эмуляторе/симуляторе:

// ...
if (Device.isDevice) {
// ...

К сожалению, на эмуляторе/симуляторе проверить работу пуш уведомлений невозможно, для проверки придется собрать приложение либо же открыть приложение в Expo Go на своем устройстве.

Только если вы настроите обработку нажатия на пуш уведомления в своем приложение, что бы открывались какие то разделы или еще какие либо действия, то с андроидом проблем не возникнет так как он открывает созданное вами приложение отдельно от ExpoGo, а на IOS он открывается напрямую в приложение, поэтому потестировать данный функционал можно будет лишь на сборке.

Как показал опыт, достаточно проверить все на андроид.


const {status: existingStatus} = await Notifications.getPermissionsAsync();
let finalStatus = existingStatus;

if (existingStatus !== "granted") {
    const {status} = await Notifications.requestPermissionsAsync();
    finalStatus = status;
}

if (finalStatus !== "granted") {
    alert("Failed to get push token for push notification!");
    return;
}

.На данном этапе мы запрашиваем у пользователя право на отправку уведомлений, если все хорошо то можем трогать дальше.


const token = (await Notifications.getExpoPushTokenAsync()).data;

Получение пуш токена для отправки пуш уведомлений с использованием сервиса ExpoGo
Пуш токен будет вида ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]

Дальше сохраняем его куда вам нужно для того что бы в последующем использовать для отправки.

Метод второй. Обработка нажатия на уведомление

import * as Notifications from "expo-notifications";

Notifications.addNotificationResponseReceivedListener(handleNotificationResponse);

function handleNotificationResponse(response)
{
    console.log(response);
}

В переменную response мы получаем ответ вида:

{
  "notification": {
    "request": {
      "trigger": {
        "remoteMessage": {
          "originalPriority": 2,
          "sentTime": 1668781805348,
          "notification": null,
          "data": {
            "message": "test",
            "title": "Test",
            "body": "{\"test\":1}",
            "scopeKey": "@your_accoutn_expo_name/project_name",
            "experienceId": "@your_accoutn_expo_name/project_name",
            "projectId": "#####-#####-#####-#####-#####"
          },
          "to": null,
          "ttl": 2419200,
          "collapseKey": null,
          "messageType": null,
          "priority": 2,
          "from": "###",
          "messageId": "0:###%6c62343ef9fd7ecd"
        },
        "channelId": null,
        "type": "push"
      },
      "content": {
        "title": "Test",
        "badge": null,
        "autoDismiss": true,
        "data": {
          "test": 1
        },
        "body": "test",
        "sound": "default",
        "sticky": false,
        "subtitle": null
      },
      "identifier": "0:###%6c62343ef9fd7ecd"
    },
    "date": 1668781805348
  },
  "actionIdentifier": "expo.modules.notifications.actions.DEFAULT"
}

Подробнее можно почитать тут.

Сервер

Для тестирования пуш уведомлений можно воспользоваться сервисам все от того же Expo Push Notifications Tool.

На странице все гениально и просто, главное вывести куда-нибудь в консоль или записать в лог файл наш токен что бы можно было вставить его в поле для токена на сайте тулзы.

На странице документации по отправке пуш уведомлений на устройства можно найти библиотеки под разные языки программирования.

Вырезка из документации

Когда вы будете готовы отправить push-уведомление, возьмите push-токен Expo из своей записи пользователя и отправьте его в API Expo с помощью простого старого HTTPS-запроса POST. Вы, вероятно, сделаете это со своего сервера (вы можете написать инструмент командной строки для их отправки, если хотите, или отправить их прямо из вашего приложения, это все равно), а команда и сообщество Expo позаботились об этом. для вас на нескольких языках:

expo-server-sdk-node for Node.js. Maintained by the Expo team.
expo-server-sdk-python for Python. Maintained by community developers.
expo-server-sdk-ruby for Ruby. Maintained by community developers.
expo-server-sdk-rust for Rust. Maintained by community developers.
ExpoNotificationsBundle for Symfony. Maintained by SolveCrew.
exponent-server-sdk-php or expo-server-sdk-php for PHP. Maintained by community developers.
exponent-server-sdk-golang for Golang. Maintained by community developers.
exponent-server-sdk-elixir for Elixir. Maintained by community developers.
expo-server-sdk-dotnet for dotnet. Maintained by community developers.
expo-server-sdk-java for Java. Maintained by community developers.
laravel-expo-notifier for Laravel. Maintained by community developers.

Полезные ссылки

Комментарии (3)


  1. mobilz
    29.11.2022 08:39
    +1

    Искренне не понимаю, почему expo-notifications не умеют их коробки работать и в ios через FCM. В новом проекте маркетологи хотели отправлять всё через FCM. т.е. и ios и android и у меня ушел день на попытки поиска инфы, как это сделать, а потом на самостоятельное изучение вопроса, т.к. инфы я не нашёл.


    1. adametsderschopfer Автор
      29.11.2022 09:48
      +1

      Подумаю о дополнение статьи на использование FCM и на IOS


      1. mobilz
        29.11.2022 10:45

        ам нет ничего сложного, просто я удивился, что нет практики в сети.