Ionic: Push-уведомления и Firebase Cloud Messaging

Сегодня я расскажу, каким образом можно отправлять push-уведомления приложениям на Ionic.

Суть в том, что уведомления отправляются через какой-нибудь провайдер. Их достаточно много, но на мой взгляд, одним из удобных является Firebase Cloud Messaging от Google. У него достаточно хорошая политика по отправке бесплатных уведомлений, неплохая ценовая политика, да и в целом понятный API.


Первым делом, необходимо зарегистрировать Google аккаунт, чтобы была доступна консоль по адресу console.firebase.google.com. После этого, необходимо добавить свое приложение:

Процесс добавления приложения в FCM.

После добавления приложения, все что нам будет нужно для отправки это Ключ сервера и Идентификатор отправителя.


Отлично, провайдера сообщений мы настроили. Теперь добавим, например, приложение Android:

Процесс добавления приложения Android.

Обратите внимание, что при добавлении приложения Android в FCM поле "Название пакета Android" должно содержать то же самое, что и атрибут id в теге widget в файле config.xml вашего приложения. Он находится в самом начале конфигурационного файла и выглядит примерно так: <widget id="app.demo" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">

На втором шаге, нам будет предложено скачать файл google-services.json. Его необходимо скачать и положить в папку platforms/android вашего приложения. После второго шага, окошко добавления можно закрывать нажав на крестик.


Теперь перейдем к настройке получения уведомлений в нашем приложении. Для этого, для начала, необходимо добавить в проект плагин Push. После его установки и подключения, нужно добавить следующий код в файл src/app/app.components.ts в метод initializeApp() в блок this.platform.ready().then(() => { ... });:

let pushOptions: PushOptions;
pushOptions = {
   android: {
      senderID: '1234567890' // Идентификатор отправителя из FCM
   },
   ios: {
      alert: 'true',
      badge: false,
      sound: 'true'
   },
   windows: {}
};

let pushObject: PushObject = this.push.init(this.pushOptions);

pushObject.on('registration').subscribe((data: any) => {
   this.api.pushRegistration().subscribe(
      let id = data.registrationId;
      // Здесь необходимо отправить id устройства на сервер и сохранить
      // Это, по сути, адресат получения уведомления
      // Выглядит он примерно так: 
      /* 
      cqklXMRYVQU:APA91bGX8H6vQGwkTbsbebLoHTKB8UwIE2tVZVLdpGjQ17FzWDSEjtQeocBWClWcXUdsV3DQHQB-_RJ88o3US0R7IgZwbQj6h94Bg9HnNp0qjrGrP6sjYWSCo92wJ8mLgsddzhD6LbN5
      */
   );
});

pushObject.on('notification').subscribe((data: any) => {
   // Это событие срабатывает, когда пользователь нажимает на уведомление
   // data содержит информацию из уведомления и любые данные, которые можно передать с сервера
});

Так же надо не забыть про импорт плагина

import { Push, PushObject, PushOptions } from '@ionic-native/push';
В данном случае я не рассматриваю подробности отображения и обработку уведомления, например можно определять, пришло уведомление когда открыто приложение или закрыто, и тому подобное. Подробности лучше подчерпнуть из документации.

Теперь маленький кусочек серверного кода на PHP, который отправляет уведомление адресату:

// Массив идентификаторов получателей, можно один, можно несколько
$tokens = ['cqklXMRYVQU:APA91bGX8H6vQGwkTbsbebLoHTKB8UwIE2tVZVLdpGjQ17FzWDSEjtQeocBWClWcXUdsV3DQHQB-_RJ88o3US0R7IgZwbQj6h94Bg9HnNp0qjrGrP6sjYWSCo92wJ8mLgsddzhD6LbN5'];

// Серверный ключ от FCM
$fcm_key = 'AAAATLIP8aI:APA91bH0Meyd9_0abMnR4q5TI-fy0m6viG8pyWhC8rOfbWvktDhFmqSjz78Naj6Vg-dZ-Or_kVc2i32t6LI8B2BuLzF0fCyMjicfJX84Z-R5VAGNwuCiJLx3M9jchD8n3f88p_08kdHZ';

// Уведомление
$fields = [
   'registration_ids' => $tokens,
   'notification' => [
      'body' => 'Сообщение уведомления',
      'title' => 'Заголовок уведомления',
      'icon' => 'notification', // Иконка уведомления
      'priority' => 'high', // Приоритет
      'color' => '#ed0039', // Цвет текста уведомления и иконки,
      'customField' => '123' // Доп. данные будут доступны в data.customField
   ]
];

// Заголовки
$headers = [
   'Authorization:key='.$fcm_key,
   'Content-Type: application/json'
];

// Отправка
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
curl_setopt($curl, CURLOPT_POST, true );
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 1000);
curl_setopt($curl, CURLOPT_FORBID_REUSE, true);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 1000);
curl_setopt($curl, CURLOPT_TIMEOUT_MS, 1000); 	
curl_setopt($curl, CURLOPT_DNS_CACHE_TIMEOUT,1000); 
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,  2);		
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($fields, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE));
$result = curl_exec($curl);
$error = curl_error($curl);
curl_close($curl);	

Кстати, чуть не забыл. Выше, название иконки указано как notification. Это название файла иконки, и файл этот должен пристутствовать в ресурсах приложения.

Чтобы не забивать себе этим голову, можно воспользовать следующей утилитой, которая наделает все необходимые иконки - https://romannurik.github.io/AndroidAssetStudio/icons-notification.html. Надо выбрать иконку, дать название (в нашем случае - notification). На выходе будет архив, в котором будет папка res/. Ее целиком надо закинуть в папку platforms/android вашего проекта. Прямо с перезаписью, если попросит.

Иконка для уведомлений.