Хранение токенов с помощью MongoDB и отправка уведомлений по темам и партиям

В нашем последнем посте мы узнали как добавить уведомления в приложение для Android. Мы рассмотрели, как генерировать токены для пользователей, отправлять их на удаленный сервер и получать сообщения, однако мы не занимались программированием на стороне сервера в том же посте, чтобы оно оставалось открытым для всех типов серверных фреймворков.

В этом посте мы обсудим фреймворк Node.js и узнаем, как обрабатывать токены, полученные от клиента, а затем использовать эти токены для отправки уведомлений клиентам. Однако настройка, обсуждаемая в этом посте, не зависит от клиента и может использоваться для всех клиентов Firebase - Android, Web или iOS.

Чтобы начать работу с Node.js, нам сначала нужно установить необходимые зависимости. Мы будем использовать экспресс-фреймворк в качестве фреймворка node.js по умолчанию и модуля BodyParser для синтаксического анализа тела почтовых запросов. MongoDB будет служить нашим основным хранилищем данных для клиентских токенов. Мы также будем использовать модуль запроса для запроса внешних URL-адресов, получения или публикации. Следующая команда установит все четыре модуля и сохранит их в package.json нашего проекта.

sudo npm i express body-parser mongodb request --save

После правильной установки модулей нам нужно создать экземпляр express as app и добавить к нему промежуточное ПО bodyparser. Пример ниже делает это.

Мы также создали экземпляр клиента MongoDB для подключения к нашей базе данных (myDatabase). Мы предоставим MongoClient местоположение нашей базы данных с помощью URL-адреса. Формат URL-адреса довольно прост. Он начинается с имени протокола, mongodb (например, http или rtsp), за которым следуют адрес местоположения и номер порта базы данных mongodb. Адрес должен быть localhost или 127.0.0.1, если база данных (демон mongod) работает на том же сервере (машине). При запуске в другом месте в качестве адреса требуется IP-адрес этого сервера. Номер порта по умолчанию, на котором работает mongodb, - 27017. Если используется другой номер порта, нам нужно указать это. Последняя часть URL-адреса - это имя базы данных, в нашем случае это myDatabase.

Мы объявим конечную точку, куда будем отправлять наши токены. Давайте добавим конечную точку POST, store, которая получит наш токен из тела запроса и, используя MongoClient, сохранит его в коллекции токенов myDatabase . Мы пытаемся подключиться к базе данных с указанным ранее URL-адресом. После подключения метод подключения предоставляет необходимую базу данных (db), а также объект исключения в качестве обратного вызова. Если не возникает исключения, мы вставим токен в коллекцию токенов с помощью метода insertOne коллекции. В приведенном выше примере тело сообщения, полученное из запроса, req.body, передается напрямую как данные для вставки, поскольку содержит только токен. Если в нем больше пар ключ-значение, мы можем получить значение токена из тела, а затем поместить его как данные для вставки.

let tokenValue = req.body.token
let data = { token: tokenValue }

Если данные вставлены без ошибок, мы снова получим обратный вызов, на который мы отправим ответ ok с кодом состояния 200. После этого просто закройте базу данных.

Итак, мы закончили с хранением токенов. Теперь мы используем эти токены для отправки уведомлений. Давайте объявим новую функцию sendNotification, которая принимает данные сообщений.

Функция данных sendNotifications принимает чистый JSON. Нам нужно преобразовать его в его строковый эквивалент с помощью JSON.stringify (…), чтобы иметь возможность отправить его в конечную точку FCM.

const headers = {
 'Authorization': 'key=<your firebase legacy server key>',
 'Content-Type': 'application/json',
 'Content-Length': dataString.length 
}

Конечная точка FCM, кроме данных, также требует нашего устаревшего ключа сервера в качестве одного из заголовков запроса. Мы можем получить ключ отстающего сервера в Firebase Console ›Настройки (значок в правом верхнем углу)› Cloud Messaging. Обратите внимание, что объявленный выше объект заголовков имеет ключ авторизации. Этот самый ключ содержит ключ сервера, который мы только что собрали из Firebase Console. Однако есть одна загвоздка. Большинство людей, впервые работающих с ключом авторизации, часто игнорируют включение key = в ключ сервера. Не надо! Кроме того, мы добавляем заголовки Content-Type и Content-Length в объект заголовков, чтобы убедиться, что сервер FCM может проанализировать заголовок и, следовательно, ключ. Оба заголовка говорят сами за себя.

Когда у нас есть готовый заголовок, мы отправляем запрос POST на сервер FCM с заголовком и данными сообщения, используя запрос, и для этого нам нужен правильно структурированный объект параметров, содержащий конечную точку FCM (uri), заголовки, метод запроса, POST и, конечно, , json (данные). Если возникнут какие-либо проблемы с пониманием, перейдите на fcm3.js и посмотрите код, это очень просто.

Итак, у нас готова базовая функция отправки уведомлений. Теперь нам нужно определить тип уведомления и соответствующим образом подготовить сообщение с данными. Сначала мы начнем с уведомления на основе темы. Уведомления на основе тем используются в сочетании с GCMPubSub, инструментом, который позволяет пользователям подписываться на определенные темы, а затем получать уведомления только по этим темам. Поговорим о GCMPubSub как-нибудь на днях. В приведенном выше примере (fcm4.js) подробно рассказывается об объекте данных, который нам нужно создать. Вы заметите, что объект данных содержит очевидные body и title. Не стесняйтесь добавлять в него больше данных.

Единственная разница между тематическим уведомлением и обычным уведомлением - целевая аудитория. В уведомлении на основе темы ожидается ключ от до с интересующей темой (ами). После добавления тем к объекту данных просто вызовите sendNotifications (..), а затем отправьте ответ (код состояния 200, ok) обратно в NotificationCenter (мы поговорим об этом чуть позже).

В то время как уведомления на основе тем ожидают темы, для обычных уведомлений требуются токены. Объект данных остается тем же, что и на основе темы, но вместо to нам нужны registration_ids для хранения массива токенов.

Функция sendToAll (…), которую мы используем для отправки уведомлений на основе токенов, также принимает regIdArray, кроме обычного сообщения, заголовка и ответа. RegIdArray - это массив всех объектов токенов, которые мы сохранили в базе данных. Подсказку можно найти ниже (fcm6.js). Поскольку это массив объектов, а не строка, нам нужно отобразить его из объекта в простой массив строк. Для этого мы будем использовать метод карты Array. В приведенном выше примере вы заметите, что мы пытались объединить идентификаторы регистрации (токены) в небольшие массивы по 1000 штук. Причина в том, что нам не разрешено отправлять уведомления более чем 1000 идентификаторам одновременно. Мы используем метод slice Array для создания меньших массивов длиной 1000.

data[‘registration_ids’] = regIdArray.slice(start, end).map((item) => { 
   return item[‘token’] 
})

Следующий фрагмент кода делает это, предполагая, что ключом для значения токена является токен. Цикл for для каждых 1000 регистрационных идентификаторов запускает их пакетную обработку и каждый раз вызывает функцию sendNotification (…). Наконец, отправляется ответ ok.

Теперь пора определить тип уведомления. Мы сделаем это в конечной точке уведомления, которую мы объявляем для Центра уведомлений (где подготавливается сообщение уведомления). Посмотрите на объявленную ниже html-страницу. У нас есть две радиокнопки. Один для sendToAll, другой для тематических. У нас также есть меню выбора (раскрывающееся), чтобы выбрать тему в случае, если установлен переключатель на основе темы. Форма выберет соответствующие данные в соответствии с выбором и отправит их в нашу конечную точку notify (POST). Мы получим наше сообщение, заголовок, тип уведомления и, если доступно, тему.

Если тип - тема, мы вызываем sendToTopics (…), передавая сообщение, заголовок, тему и объект ответа. Если нет, мы подключаемся к нашей базе данных с помощью MongoClient и вызываем sendToAll (…). Переданные ему параметры останутся такими же, кроме одного. Тема заменяется массивом токенов, который мы получаем от вызова базы данных (найти?).

Вот и все. Мы успешно создали две конечные точки: одну для хранения токенов, а другую для отправки уведомления с использованием темы или токенов. Мы также создали центр уведомлений (notifcenter.html), используя html, css и немного JavaScript, чтобы мы могли создать тело уведомления и выбрать его тип. Центр уведомлений доступен как запрос на получение по адресу ‘/ notifications’ (см. Fcm1.js). Не стесняйтесь делиться своими проблемами или опытом в комментариях ниже.

Примечание: эта статья была впервые опубликована на Context Neutral. Посетите сайт, чтобы найти более актуальные и обновленные статьи об Android, Node.js, AWS и многом другом.