Руководство по отправке push-уведомлений в приложения React Native с помощью Центров уведомлений Azure через серверную службу
В этом руководстве вы используете Центры уведомлений Azure
Серверная часть веб-API
Эти операции обрабатываются с помощью пакета SDK для центров уведомлений для внутренних операций. Дополнительные сведения о общем подходе приведены в документации по регистрации из серверной части приложения документации.
В этом руководстве описаны следующие действия.
- настройка служб push-уведомлений и Центров уведомлений Azure.
- создание серверного приложения ASP.NET Core Web API.
- Создание кроссплатформенного приложения React Native.
- настроить собственный проект Android для push-уведомлений.
- Настроить собственный проект iOS для push-уведомлений.
- протестировать решение.
Необходимые условия
Для выполнения дальнейших инструкций вам потребуется:
- подписке Azure, где можно создавать ресурсы и управлять ими.
- Компьютер Mac с установленным Visual Studio для Mac (или компьютер с Visual Studio 2019 с мобильной разработки с помощью рабочей нагрузки .NET).
- Возможность запуска приложения на Android (физические или эмуляторные устройства) или iOS (только физические устройства).
Для Android необходимо иметь следующее:
- Разработчик разблокировал физическое устройство или эмулятор (с установленным API 26 и более поздних версий с установленными службами Google Play).
Для iOS необходимо:
- Активная учетной записи разработчика Apple.
- Физическое устройство iOS, зарегистрированное в учетной записи разработчика(под управлением iOS 13.0 и более поздних версий).
- сертификата разработки
.p12 , установленного в цепочке ключей , что позволяетзапускать приложение на физическом устройстве .
Заметка
Симулятор iOS не поддерживает удаленные уведомления, поэтому при изучении этого примера в iOS требуется физическое устройство. Однако для выполнения этого руководства не требуется запускать приложение как на Android, так и iOS.
Вы можете выполнить действия, описанные в этом примере с использованием первых принципов без предыдущего опыта. Тем не менее, вы получите преимущество от знакомства со следующими аспектами.
- портал разработчика Apple
- ASP.NET Core
- консоль Google Firebase
- Microsoft Azure и отправлять push-уведомления в приложения iOS с помощью Центров уведомлений Azure.
- React Native.
Описанные ниже действия предназначены для Visual Studio для Mac и Visual Studio Code, но это можно сделать с помощью Visual Studio 2019.
Настройка служб push-уведомлений и Центра уведомлений Azure
В этом разделе описано, как настроить Firebase Cloud Messaging (FCM) и службы push-уведомлений Apple (APNS). Затем вы создаете и настраиваете концентратор уведомлений для работы с этими службами.
Создание проекта Firebase и включение Firebase Cloud Messaging для Android
Войдите вконсоли Firebase
. Создайте проект Firebase, введющий PushDemo в качестве имени проекта. Заметка
Для вас будет создано уникальное имя. По умолчанию это состоит из нижнего регистра имени, указанного плюс созданного числа, разделенного дефисом. Это можно изменить, если вы хотите предоставить его по-прежнему глобально уникальным.
После создания проекта выберите Добавить Firebase в приложение Android.
На странице приложения Android
добавить Firebase выполните следующие действия. В поле имя пакета Androidвведите имя пакета. Например,
com.<organization_identifier>.<package_name>
.Выберите Зарегистрировать приложение.
Выберите Скачать google-services.json. Затем сохраните файл в локальную папку для последующего использования и нажмите кнопку Далее.
Выберите Далее.
Выберите Продолжить консоль
Заметка
Если кнопка
продолжить консоли не включена, из-за проверки установкинажмите кнопку Пропустить этот шаг .
В консоли Firebase выберите шестеренку для проекта. Затем выберите параметры проекта.
Заметка
Если вы не скачали файл google-services.json, его можно скачать на этой странице.
Перейдите на вкладку Cloud Messaging в верхней части. Скопируйте и сохраните ключа сервера
для последующего использования. Это значение используется для настройки концентратора уведомлений.
Регистрация приложения iOS для push-уведомлений
Чтобы отправить push-уведомления в приложение iOS, зарегистрируйте приложение в Apple, а также зарегистрируйтесь для push-уведомлений.
Если вы еще не зарегистрировали приложение, перейдите на портал подготовки iOS
в Центре разработчиков Apple. Войдите на портал с помощью идентификатора Apple ID, перейдите к сертификатам, идентификаторам & профилям, а затем выберите идентификаторы. Щелкните +, чтобы зарегистрировать новое приложение. На экране Регистрация нового идентификатора выберите идентификаторы приложений переключателя. Затем выберите Продолжить.
Обновите следующие три значения для нового приложения, а затем выберите Продолжить:
описание. Введите описательное имя приложения.
идентификатор пакета : введите идентификатор пакета формыcom. , как упоминалось вруководстве по распространению приложенийorganization_identifier . product_name . На следующем снимке экрана значение mobcat
используется в качестве идентификатора организации, а значение PushDemo используется в качестве имени продукта.страницы идентификатора приложения
push-уведомлений . Проверьте параметрpush-уведомлений в разделе Возможности .форма
Это действие создает идентификатор приложения и запросы, которые вы подтверждаете информацию. Выберите продолжить, а затем выберите Зарегистрировать, чтобы подтвердить новый идентификатор приложения.
После выбора регистрациивы увидите новый идентификатор приложения в виде элемента строки на странице Сертификатов, идентификаторов & профилей.
На странице "Сертификаты
идентификаторы" & профили в разделе "Идентификаторы" найдите созданный элемент строки идентификатор а приложения. Затем выберите строку, чтобы отобразить экран Изменить конфигурацию идентификатора приложения.
Создание сертификата для центров уведомлений
Сертификат необходим, чтобы центр уведомлений работал с службами push-уведомлений Apple (APNS) и может быть предоставлен одним из двух способов:
создание push-сертификата p12, который можно отправить непосредственно в центр уведомлений (исходного подхода)
создание сертификата p8, который можно использовать для проверки подлинности на основе маркеров (более новый и рекомендуемый подход)
Более новый подход имеет ряд преимуществ, как описано в проверке подлинности на основе токенов (HTTP/2) дляAPNS. Для конкретных сценариев требуется меньше шагов, но также требуется. Однако для обоих подходов были предоставлены шаги, так как они будут работать в целях этого руководства.
ВАРИАНТ 1. Создание push-сертификата p12, который можно отправить непосредственно в Центр уведомлений
На компьютере Mac запустите средство доступа к цепочке ключей. Его можно открыть из папки Служебные программы или папку Other на панели запуска.
Выберите
доступ к цепочке ключей , развернитепомощника по сертификату, а затем выберите Запросить сертификат из центра сертификации .Заметка
По умолчанию доступ к цепочке ключей выбирает первый элемент в списке. Это может быть проблема, если вы находитесь в категории сертификатов и Центр сертификации Apple По всему миру разработчиков не является первым элементом в списке. Убедитесь, что у вас есть элемент, отличный от ключа, или Центр сертификации Apple По всему миру разработчиков ключ выбран, прежде чем создавать CSR (запрос на подписи сертификатов).
Выберите
адрес электронной почты пользователя, введите значение общего имени , убедитесь, чтосохранено на диске , а затем нажмите кнопкуПродолжить . Оставьте адрес электронной почты ЦС пустым, так как он не требуется.Введите имя файла
запроса подписи сертификата (CSR) в сохранить как , выберите расположение вгде , а затем нажмите кнопкуСохранить .Это действие сохраняет CSR-файл в выбранном расположении. Расположение по умолчанию — desktop. Помните расположение, выбранное для файла.
Вернитесь на страницу сертификатов, идентификаторов & профилей на портале подготовки iOS, прокрутите страницу вниз до флажка push-уведомлений, а затем выберите Настроить для создания сертификата.
Появится появится окно TLS/SSL-сертификат ов службы push-уведомлений Apple. Нажмите кнопку создать сертификат в разделе Сертификат TLS/SSL.
Отображается экран создание нового сертификата.
Заметка
В этом руководстве используется сертификат разработки. При регистрации рабочего сертификата используется тот же процесс. Просто убедитесь, что при отправке уведомлений используется тот же тип сертификата.
Выберите Выбрать файл, перейдите к расположению, где вы сохранили CSR-файл, а затем дважды щелкните имя сертификата, чтобы загрузить его. Затем выберите Продолжить.
После создания сертификата на портале нажмите кнопку "Скачать". Сохраните сертификат и запомните расположение, в котором он сохранен.
Сертификат скачан и сохранен на компьютер в папке загрузки.
Заметка
По умолчанию скачанный сертификат разработки называется aps_development.cer.
Дважды щелкните скачанный push-сертификат aps_development.cer. Это действие устанавливает новый сертификат в цепочке ключей, как показано на следующем рисунке:
Заметка
Хотя имя в сертификате может отличаться, имя будет префиксировано с помощью push-служб Apple Development iOS и имеет соответствующий идентификатор пакета.
В access Control + Click на новом push-сертификате, созданном в категории сертификатов. Выберите экспорт, назовите файл, выберите формат p12 и нажмите кнопку Сохранить.
Вы можете защитить сертификат паролем, но пароль необязателен. Нажмите кнопку ОК, если вы хотите обойти создание пароля. Запишите имя файла и расположение экспортированного сертификата p12. Они используются для включения проверки подлинности с помощью APN.
Заметка
Имя и расположение файла p12 могут отличаться от того, что изображено в этом руководстве.
ВАРИАНТ 2. Создание сертификата p8, который можно использовать для проверки подлинности на основе токенов
Запишите следующие сведения:
- префикс идентификатора приложения
( идентификатор команды ) - идентификатор пакета
- префикс идентификатора приложения
Вернитесь в сертификаты, идентификаторы & профили, щелкните ключи.
Заметка
Если у вас уже есть ключ, настроенный для APNS, можно повторно использовать сертификат p8, скачанный сразу после его создания. В этом случае можно игнорировать шаги 3 через 5.
Нажмите кнопку + (или кнопку Создать ключ), чтобы создать новый ключ.
Укажите подходящее значение имени ключа, а затем проверьте параметр службы push-уведомлений Apple (APNS), а затем нажмите кнопку Продолжить, а затем Зарегистрировать на следующем экране.
Щелкните Скачать, а затем переместите файл p8 (префикс с AuthKey_) в безопасный локальный каталог, а затем щелкните Готово.
Заметка
Не забудьте сохранить p8-файл в безопасном месте (и сохранить резервную копию). После скачивания ключа его невозможно повторно скачать по мере удаления копии сервера.
На клавишищелкните созданный ключ (или существующий ключ, если вы решили использовать это).
Запишите значение идентификатора ключа
. Откройте сертификат p8 в подходящем приложении, например Visual Studio Code. Запишите значение ключа (между закрытым ключом -----BEGIN----- и -----END PRIVATE KEY-----).
ЗАКРЫТЫЙ КЛЮЧ -----BEGIN-----
<key_value>
-----END PRIVATE KEY-----Заметка
Это значение маркера , которое будет использоваться позже для настройки концентратора уведомлений.
В конце этих действий вам должны быть приведены следующие сведения для последующего использования в Настройка концентратора уведомлений с помощью сведений APNS:
- идентификатор команды (см. шаг 1)
- идентификатор пакета (см. шаг 1)
- идентификатор ключа (см. шаг 7)
- значение маркера (значение ключа p8, полученное на шаге 8)
Создание профиля подготовки для приложения
Вернитесь кпортала подготовки iOS
, выберите сертификаты, идентификаторы & профили , выберитепрофили в меню слева, а затем выберите, чтобы создать новый профиль. Появится экран Регистрация нового профиля подготовки. Выберите
разработки приложений iOS в разделе "Разработка " в качестве типа профиля подготовки, а затем выберите "Продолжить ".Затем выберите идентификатор приложения, созданный в раскрывающемся списке идентификатор приложения, и выберите Продолжить.
В окне Выбор сертификатов выберите сертификат разработки, используемый для подписывания кода, и выберите Продолжить.
Заметка
Этот сертификат не является push-сертификатом, созданным на предыдущем шаге . Это ваш сертификат разработки. Если он не существует, необходимо создать его, так как это предварительный для этого руководства. Сертификаты разработчика можно создавать на портале разработчиков Apple,с помощью Xcode или Visual Studio.
Вернитесь на страницу профилей
, идентификаторы & профилей , выберитепрофили в меню слева, а затем выберите, чтобы создать новый профиль. Появится экран Регистрация нового профиля подготовки. В окне Выбор сертификатов выберите созданный сертификат разработки. Затем выберите Продолжить.
Затем выберите устройства, которые будут использоваться для тестирования, и выберите Продолжить.
Наконец, выберите имя профиля в имя профиля подготовкии выберите Создать.
При создании нового профиля подготовки выберите Скачать. Помните расположение, в котором он сохранен.
Перейдите к расположению профиля подготовки и дважды щелкните его, чтобы установить его на компьютере разработки.
Создание центра уведомлений
В этом разделе описано, как создать концентратор уведомлений и настроить проверку подлинности с помощью APNS. Вы можете использовать push-сертификат p12 или проверку подлинности на основе маркеров. Если вы хотите использовать созданный центр уведомлений, можно перейти к шагу 5.
Войдите в Azure.
Щелкните Создать ресурс, а затем найдите и выберите Центр уведомлений, а затем щелкните Создать.
Обновите следующие поля, а затем щелкните Создать:
БАЗОВЫЕ СВЕДЕНИЯ
подписка : выберите целевую подписку из раскрывающегося списка
группа ресурсов : создать новую группу ресурсов (или выбрать существующую)СВЕДЕНИЯ О ПРОСТРАНСТВЕ ИМЕН
пространство имен центра уведомлений : Введите глобально уникальное имя для пространства имен центра уведомлений
Заметка
Убедитесь, что для этого поля выбран параметр "Создать новую".
СВЕДЕНИЯ ЦЕНТРА УВЕДОМЛЕНИЙ
Центр уведомлений : введите имя центра уведомлений
расположение: Выбрать подходящее расположение из раскрывающегося списка
ценовая категория : Сохранить параметр бесплатного по умолчаниюЗаметка
Если вы не достигли максимального количества центров на уровне "Бесплатный".
После подготовки Центра уведомлений
перейдите к ресурсу. Перейдите к новому центру уведомлений .
Выберите политики доступа из списка (в разделе MANAGE).
Запишите значения имени политики
вместе со значениями строки подключения .
Настройка центра уведомлений с помощью сведений APNS
В разделеслужб уведомлений
Заметка
Используйте рабочую для режима приложений только в том случае, если вы хотите отправлять push-уведомления пользователям, которые приобрели приложение из магазина.
ВАРИАНТ 1. Использование push-сертификата P12
Выберитесертификата
. Щелкните значок файла.
Выберите P12-файл, экспортируемый ранее, и выберите Открыть.
При необходимости укажите правильный пароль.
Выберите режим песочницы.
Выберите Сохранить.
ВАРИАНТ 2. Использование проверки подлинности на основе токенов
Выберите токена.
Введите следующие значения, полученные ранее:
- идентификатор ключа
- идентификатор пакета
- идентификатор команды
- маркера
Выберите песочницу.
Выберите Сохранить.
Настройка концентратора уведомлений с помощью данных FCM
- Выберите Google (GCM/FCM) в разделе "Параметры " меню слева.
- Введите ключ сервера , который вы указали из консоли Google Firebase.
- Выберите Сохранить на панели инструментов.
Создание серверного приложения веб-API ASP.NET Core
В этом разделе описано, как создать серверную часть веб-API
Создание веб-проекта
В Visual Studioвыберите файл>новый.
Выберите .NET Core>App>ASP.NET Core>API>Далее.
В диалоговом окне Настройка нового веб- API ASP.NET Core Web API выберите Target Framework.NET Core 3.1.
Введите PushDemoApi для имени проекта и выберите Создать.
Начните отладку (команда + ВВОД) для тестирования шаблонного приложения.
Заметка
Шаблонное приложение настроено для использования WeatherForecastController в качестве launchUrl. Этот параметр задан в Свойства>launchSettings.json.
Если вам будет предложено получить недопустимый сертификат разработки найден сообщение:
Щелкните Да, чтобы согласиться запустить средство dotnet dev-certs https, чтобы устранить эту проблему. Затем средство dotnet dev-certs https предложит ввести пароль для сертификата и пароля для цепочки ключей.
Щелкните Да при появлении запроса на установить и доверять новому сертификату, а затем введите пароль для цепочки ключей.
Разверните папку контроллеров
, а затем удалите WeatherForecastController.cs .Удаление WeatherForecast.cs.
Настройте локальные значения конфигурации с помощью средства Secret Manager. Разделение секретов из решения гарантирует, что они не в конечном итоге в системе управления версиями. Откройте терминал перейдите в каталог файла проекта и выполните следующие команды:
dotnet user-secrets init dotnet user-secrets set "NotificationHub:Name" <value> dotnet user-secrets set "NotificationHub:ConnectionString" <value>
Замените значения заполнителей собственным именем концентратора уведомлений и значениями строки подключения. Вы записали их в разделе создания центра уведомлений. В противном случае их можно найти в Azure.
NotificationHub:Name:
См.в сводке Essentials в верхней частиобзора . NotificationHub:ConnectionString:
См. defaultFullSharedAccessSignature в политиках доступаЗаметка
В рабочих сценариях можно просмотреть такие варианты, как Azure KeyVault для безопасного хранения строки подключения. Для простоты секреты будут добавлены в параметры приложения службы приложений Azure .
Проверка подлинности клиентов с помощью ключа API (необязательно)
Ключи API не так безопасны, как маркеры, но достаточно для целей этого руководства. Ключ API можно легко настроить с помощью ASP.NET ПО промежуточного слоя.
Добавьте ключ API в значения локальной конфигурации.
dotnet user-secrets set "Authentication:ApiKey" <value>
Заметка
Замените значение заполнителя собственным и запишите его.
Элемент управления щелкните в проектеPushDemoApi , выберитесоздать папку в меню"Добавить ", а затем выберитеДобавить проверки подлинностив качестве имени папки .Элемент управления щелкните в папке проверки подлинности, а затем выберите Создать файл... в меню"Добавить ".Выберите
Общие пустого класса , введитеApiKeyAuthOptions.cs дляимени, а затем нажмите кнопку Создать добавить следующую реализацию.using Microsoft.AspNetCore.Authentication; namespace PushDemoApi.Authentication { public class ApiKeyAuthOptions : AuthenticationSchemeOptions { public const string DefaultScheme = "ApiKey"; public string Scheme => DefaultScheme; public string ApiKey { get; set; } } }
Добавьте еще один пустой класс в папку проверки подлинности с именем ApiKeyAuthHandler.cs, а затем добавьте следующую реализацию.
using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Text.Encodings.Web; using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace PushDemoApi.Authentication { public class ApiKeyAuthHandler : AuthenticationHandler<ApiKeyAuthOptions> { const string ApiKeyIdentifier = "apikey"; public ApiKeyAuthHandler( IOptionsMonitor<ApiKeyAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock) {} protected override Task<AuthenticateResult> HandleAuthenticateAsync() { string key = string.Empty; if (Request.Headers[ApiKeyIdentifier].Any()) { key = Request.Headers[ApiKeyIdentifier].FirstOrDefault(); } else if (Request.Query.ContainsKey(ApiKeyIdentifier)) { if (Request.Query.TryGetValue(ApiKeyIdentifier, out var queryKey)) key = queryKey; } if (string.IsNullOrWhiteSpace(key)) return Task.FromResult(AuthenticateResult.Fail("No api key provided")); if (!string.Equals(key, Options.ApiKey, StringComparison.Ordinal)) return Task.FromResult(AuthenticateResult.Fail("Invalid api key.")); var identities = new List<ClaimsIdentity> { new ClaimsIdentity("ApiKeyIdentity") }; var ticket = new AuthenticationTicket( new ClaimsPrincipal(identities), Options.Scheme); return Task.FromResult(AuthenticateResult.Success(ticket)); } } }
Добавьте еще один
пустой класс вApiKeyAuthenticationBuilderExtensions.cs папку проверки подлинности, а затем добавьте следующую реализацию. using System; using Microsoft.AspNetCore.Authentication; namespace PushDemoApi.Authentication { public static class AuthenticationBuilderExtensions { public static AuthenticationBuilder AddApiKeyAuth( this AuthenticationBuilder builder, Action<ApiKeyAuthOptions> configureOptions) { return builder .AddScheme<ApiKeyAuthOptions, ApiKeyAuthHandler>( ApiKeyAuthOptions.DefaultScheme, configureOptions); } } }
Заметка
Этот метод расширения упрощает код конфигурации ПО промежуточного слоя в Startup.cs что делает его более удобочитаемым и, как правило, проще следовать.
В Startup.csобновите метод ConfigureServices, чтобы настроить проверку подлинности ключа API под вызовом служб . Метод AddControllers.
using PushDemoApi.Authentication; using PushDemoApi.Models; using PushDemoApi.Services; public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = ApiKeyAuthOptions.DefaultScheme; options.DefaultChallengeScheme = ApiKeyAuthOptions.DefaultScheme; }).AddApiKeyAuth(Configuration.GetSection("Authentication").Bind); }
По-прежнему в
Startup.cs обновите методConfigure , чтобывызвать метод UseAuthentication иМетоды расширения UseAuthorization вIApplicationBuild er приложения. Убедитесь, что эти методы вызываются после UseRouting и до приложения. UseEndpoints.public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
Заметка
Вызов UseAuthentication регистрирует ПО промежуточного слоя, которое использует ранее зарегистрированные схемы проверки подлинности (из ConfigureServices). Это необходимо вызвать перед любым ПО промежуточного слоя, которое зависит от проверки подлинности пользователей.
Добавление зависимостей и настройка служб
ASP.NET Core поддерживает шаблон внедрения зависимостей (DI) программного обеспечения, который является способом достижения инверсии управления (IoC) между классами и их зависимостями.
Использование концентратора уведомлений и пакета SDK для центров уведомлений для внутренних операций инкапсулируется в службе. Служба зарегистрирована и доступна с помощью подходящей абстракции.
Элемент управления + щелкните в папке зависимостей, а затем выберите Управление пакетами NuGet....
Выполните поиск Microsoft.Azure.NotificationHubs и убедитесь, что он установлен.
Щелкните Добавить пакеты, а затем щелкните Принять при появлении запроса на принятие условий лицензии.
Элемент управления щелкните в проектеPushDemoApi , выберитесоздать папку в меню"Добавить ", а затем щелкнитеДобавить с помощью моделейв качестве имени папки .Элемент управления Щелкните в папке модели, а затем выберитеСоздать файл... в менюДобавить .Выберите
Общие пустого класса , введитеPushTemplates.cs дляимени, а затем нажмите кнопку Создать добавить следующую реализацию.namespace PushDemoApi.Models { public class PushTemplates { public class Generic { public const string Android = "{ \"notification\": { \"title\" : \"PushDemo\", \"body\" : \"$(alertMessage)\"}, \"data\" : { \"action\" : \"$(alertAction)\" } }"; public const string iOS = "{ \"aps\" : {\"alert\" : \"$(alertMessage)\"}, \"action\" : \"$(alertAction)\" }"; } public class Silent { public const string Android = "{ \"data\" : {\"message\" : \"$(alertMessage)\", \"action\" : \"$(alertAction)\"} }"; public const string iOS = "{ \"aps\" : {\"content-available\" : 1, \"apns-priority\": 5, \"sound\" : \"\", \"badge\" : 0}, \"message\" : \"$(alertMessage)\", \"action\" : \"$(alertAction)\" }"; } } }
Заметка
Этот класс содержит полезные данные уведомления с маркерами для универсальных и автоматических уведомлений, необходимых для этого сценария. Полезные данные определяются вне установки, чтобы разрешить экспериментирование без необходимости обновлять существующие установки через службу. Обработка изменений в установках таким образом выходит за рамки этого руководства. Для рабочей среды рассмотрите возможность пользовательских шаблонов.
Добавьте еще один
пустой класс в папку моделейс именем DeviceInstallation.cs , а затем добавьте следующую реализацию.using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace PushDemoApi.Models { public class DeviceInstallation { [Required] public string InstallationId { get; set; } [Required] public string Platform { get; set; } [Required] public string PushChannel { get; set; } public IList<string> Tags { get; set; } = Array.Empty<string>(); } }
Добавьте еще один пустой класс в папку Models с именем NotificationRequest.cs, а затем добавьте следующую реализацию.
using System; namespace PushDemoApi.Models { public class NotificationRequest { public string Text { get; set; } public string Action { get; set; } public string[] Tags { get; set; } = Array.Empty<string>(); public bool Silent { get; set; } } }
Добавьте еще один
пустой класс в папку моделей с именемNotificationHubOptions.cs , а затем добавьте следующую реализацию.using System.ComponentModel.DataAnnotations; namespace PushDemoApi.Models { public class NotificationHubOptions { [Required] public string Name { get; set; } [Required] public string ConnectionString { get; set; } } }
Добавьте новую папку в проект PushDemoApi с именем Services.
Добавьте пустого интерфейса
в папку служб с именем INotificationService.cs , а затем добавьте следующую реализацию.using System.Threading; using System.Threading.Tasks; using PushDemoApi.Models; namespace PushDemoApi.Services { public interface INotificationService { Task<bool> CreateOrUpdateInstallationAsync(DeviceInstallation deviceInstallation, CancellationToken token); Task<bool> DeleteInstallationByIdAsync(string installationId, CancellationToken token); Task<bool> RequestNotificationAsync(NotificationRequest notificationRequest, CancellationToken token); } }
Добавьте
пустой класс в папку служб с именемNotificationHubsService.cs , а затем добавьте следующий код для реализации интерфейсаINotificationService :using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.NotificationHubs; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using PushDemoApi.Models; namespace PushDemoApi.Services { public class NotificationHubService : INotificationService { readonly NotificationHubClient _hub; readonly Dictionary<string, NotificationPlatform> _installationPlatform; readonly ILogger<NotificationHubService> _logger; public NotificationHubService(IOptions<NotificationHubOptions> options, ILogger<NotificationHubService> logger) { _logger = logger; _hub = NotificationHubClient.CreateClientFromConnectionString( options.Value.ConnectionString, options.Value.Name); _installationPlatform = new Dictionary<string, NotificationPlatform> { { nameof(NotificationPlatform.Apns).ToLower(), NotificationPlatform.Apns }, { nameof(NotificationPlatform.Fcm).ToLower(), NotificationPlatform.Fcm } }; } public async Task<bool> CreateOrUpdateInstallationAsync(DeviceInstallation deviceInstallation, CancellationToken token) { if (string.IsNullOrWhiteSpace(deviceInstallation?.InstallationId) || string.IsNullOrWhiteSpace(deviceInstallation?.Platform) || string.IsNullOrWhiteSpace(deviceInstallation?.PushChannel)) return false; var installation = new Installation() { InstallationId = deviceInstallation.InstallationId, PushChannel = deviceInstallation.PushChannel, Tags = deviceInstallation.Tags }; if (_installationPlatform.TryGetValue(deviceInstallation.Platform, out var platform)) installation.Platform = platform; else return false; try { await _hub.CreateOrUpdateInstallationAsync(installation, token); } catch { return false; } return true; } public async Task<bool> DeleteInstallationByIdAsync(string installationId, CancellationToken token) { if (string.IsNullOrWhiteSpace(installationId)) return false; try { await _hub.DeleteInstallationAsync(installationId, token); } catch { return false; } return true; } public async Task<bool> RequestNotificationAsync(NotificationRequest notificationRequest, CancellationToken token) { if ((notificationRequest.Silent && string.IsNullOrWhiteSpace(notificationRequest?.Action)) || (!notificationRequest.Silent && (string.IsNullOrWhiteSpace(notificationRequest?.Text)) || string.IsNullOrWhiteSpace(notificationRequest?.Action))) return false; var androidPushTemplate = notificationRequest.Silent ? PushTemplates.Silent.Android : PushTemplates.Generic.Android; var iOSPushTemplate = notificationRequest.Silent ? PushTemplates.Silent.iOS : PushTemplates.Generic.iOS; var androidPayload = PrepareNotificationPayload( androidPushTemplate, notificationRequest.Text, notificationRequest.Action); var iOSPayload = PrepareNotificationPayload( iOSPushTemplate, notificationRequest.Text, notificationRequest.Action); try { if (notificationRequest.Tags.Length == 0) { // This will broadcast to all users registered in the notification hub await SendPlatformNotificationsAsync(androidPayload, iOSPayload, token); } else if (notificationRequest.Tags.Length <= 20) { await SendPlatformNotificationsAsync(androidPayload, iOSPayload, notificationRequest.Tags, token); } else { var notificationTasks = notificationRequest.Tags .Select((value, index) => (value, index)) .GroupBy(g => g.index / 20, i => i.value) .Select(tags => SendPlatformNotificationsAsync(androidPayload, iOSPayload, tags, token)); await Task.WhenAll(notificationTasks); } return true; } catch (Exception e) { _logger.LogError(e, "Unexpected error sending notification"); return false; } } string PrepareNotificationPayload(string template, string text, string action) => template .Replace("$(alertMessage)", text, StringComparison.InvariantCulture) .Replace("$(alertAction)", action, StringComparison.InvariantCulture); Task SendPlatformNotificationsAsync(string androidPayload, string iOSPayload, CancellationToken token) { var sendTasks = new Task[] { _hub.SendFcmNativeNotificationAsync(androidPayload, token), _hub.SendAppleNativeNotificationAsync(iOSPayload, token) }; return Task.WhenAll(sendTasks); } Task SendPlatformNotificationsAsync(string androidPayload, string iOSPayload, IEnumerable<string> tags, CancellationToken token) { var sendTasks = new Task[] { _hub.SendFcmNativeNotificationAsync(androidPayload, tags, token), _hub.SendAppleNativeNotificationAsync(iOSPayload, tags, token) }; return Task.WhenAll(sendTasks); } } }
Заметка
Выражение тега, предоставленное для SendTemplateNotificationAsync, ограничено 20 тегами. Это ограничение ограничено 6 для большинства операторов, но выражение содержит только OR (||) в этом случае. Если в запросе существует более 20 тегов, они должны быть разделены на несколько запросов. Дополнительные сведения см. в документации по
выражения маршрутизации и тегов. В
Startup.cs обновите методConfigureServices , чтобы добавить NotificationHubsServiceNotificationHubsService в качестве единой реализации INotificationService .using PushDemoApi.Models; using PushDemoApi.Services; public void ConfigureServices(IServiceCollection services) { ... services.AddSingleton<INotificationService, NotificationHubService>(); services.AddOptions<NotificationHubOptions>() .Configure(Configuration.GetSection("NotificationHub").Bind) .ValidateDataAnnotations(); }
Создание API уведомлений
Элемент управления щелкните в папке контроллеров, а затем выберите Создать файл... в менюДобавить .Выберитекласс контроллера веб-API
ASP.NET Core , введите NotificationsController дляимени, а затем нажмите кнопку Создать .Заметка
Если вы используете Visual Studio 2019, выберите контроллер API с помощью шаблона действий чтения и записи.
Добавьте следующие пространства имен в начало файла.
using System.ComponentModel.DataAnnotations; using System.Net; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using PushDemoApi.Models; using PushDemoApi.Services;
Обновите шаблонный контроллер, чтобы он был производным от ControllerBase и украшен атрибутом ApiController.
[ApiController] [Route("api/[controller]")] public class NotificationsController : ControllerBase { // Templated methods here }
Заметка
Базовый класс контроллера
обеспечивает поддержку представлений, но в этом случае это не требуется, поэтому вместо этого можно использовать ControllerBase ControllerBase. Если вы используете Visual Studio 2019, этот шаг можно пропустить. Если вы решили завершить проверку подлинности клиентов
с помощью раздела ключа API, необходимо также украсить notificationsControllerс помощью атрибута авторизовать . [Authorize]
Обновите конструктор, чтобы принять зарегистрированный экземпляр INotificationService в качестве аргумента и назначить его элементу чтения.
readonly INotificationService _notificationService; public NotificationsController(INotificationService notificationService) { _notificationService = notificationService; }
В
launchSettings.json (в папке свойств) измените launchUrl сна api/notifications , чтобы он соответствовал URL-адресу, указанному в атрибутеRegistrationsController Route .Запустите отладку (команда + ВВОД) для проверки работы приложения с новым NotificationsController и возвращает состояние 401 Unauthorized.
Заметка
Visual Studio может не запускать приложение в браузере автоматически. Вы будете использовать Postman для тестирования API с этой точки.
На новой вкладке Postman задайте для запроса GET. Введите приведенный ниже адрес, заменив заполнитель
httpsapplicationUrl applicationUrl , найденный вlaunchSettings.json свойств. <applicationUrl>/api/notifications
Заметка
applicationUrl должен быть "https://localhost:5001" для профиля по умолчанию. Если вы используете IIS (по умолчанию в Visual Studio 2019 в Windows), следует использовать applicationUrl, указанные в элементе iisSettings. Если адрес неверный, вы получите ответ 404.
Если вы решили выполнить аутентификацию клиентов с помощью раздела ключа API, обязательно настройте заголовки запроса, чтобы включить значение apikey.
Ключ Ценность apikey <your_api_key> Нажмите кнопку "Отправить
". Заметка
Вы должны получить состояние
200 OK с некоторыми содержимого JSON .Если вы получаете предупреждение
проверки SSL-сертификата , можно переключить проверку проверки SSL-сертификата запроса впараметровPostman . Замените методы шаблонного класса в NotificationsController.cs следующим кодом.
[HttpPut] [Route("installations")] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.UnprocessableEntity)] public async Task<IActionResult> UpdateInstallation( [Required]DeviceInstallation deviceInstallation) { var success = await _notificationService .CreateOrUpdateInstallationAsync(deviceInstallation, HttpContext.RequestAborted); if (!success) return new UnprocessableEntityResult(); return new OkResult(); } [HttpDelete()] [Route("installations/{installationId}")] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.UnprocessableEntity)] public async Task<ActionResult> DeleteInstallation( [Required][FromRoute]string installationId) { var success = await _notificationService .DeleteInstallationByIdAsync(installationId, CancellationToken.None); if (!success) return new UnprocessableEntityResult(); return new OkResult(); } [HttpPost] [Route("requests")] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.UnprocessableEntity)] public async Task<IActionResult> RequestPush( [Required]NotificationRequest notificationRequest) { if ((notificationRequest.Silent && string.IsNullOrWhiteSpace(notificationRequest?.Action)) || (!notificationRequest.Silent && string.IsNullOrWhiteSpace(notificationRequest?.Text))) return new BadRequestResult(); var success = await _notificationService .RequestNotificationAsync(notificationRequest, HttpContext.RequestAborted); if (!success) return new UnprocessableEntityResult(); return new OkResult(); }
Создание приложения API
Теперь вы создадите приложения API
Щелкните Создать ресурс, а затем найдите и выберите приложение API, а затем щелкните Создать.
Обновите следующие поля, а затем щелкните Создать.
имя приложения :
Введите глобально уникальное имя приложения APIподписка :
Выберите тот же целевой подписки, в которую вы создали концентратор уведомлений.Группа ресурсов :
Выберите ту же группу ресурсов, в которую вы создали концентратор уведомлений.план или расположение службы приложений :
Создание плана службы приложенийЗаметка
Переход от параметра по умолчанию к плану, который включает поддержку SSL-. В противном случае при работе с мобильным приложением необходимо выполнить соответствующие действия, чтобы предотвратить блокировку запросов http.
Application Insights:
Сохраните предлагаемый параметр (новый ресурс будет создан с помощью этого имени) или выберите существующий ресурс.После подготовки приложения API
перейдите к ресурсу. Запишите свойство URL-адреса
в сводке Essentials в верхней частиобзора. Этот URL-адрес — это серверная конечная точка, которая будет использоваться далее в этом руководстве. Заметка
URL-адрес использует имя приложения API, указанное ранее, с форматом
https://<app_name>.azurewebsites.net
.Выберите конфигурации
в списке (в разделепараметров ). Для каждого из приведенных ниже параметров щелкните
Параметр нового приложения , чтобы ввести имяи значение , а затем нажмите кнопкуОК .Имя Ценность Authentication:ApiKey
<api_key_value> NotificationHub:Name
<hub_name_value> NotificationHub:ConnectionString
<hub_connection_string_value> Заметка
Это те же параметры, которые вы определили ранее в параметрах пользователя. Их можно скопировать. Параметр проверки подлинности :ApiKey требуется только в том случае, если вы решили выполнить проверку подлинности клиентов с помощью раздела ключа API. В рабочих сценариях можно просмотреть такие варианты, как Azure KeyVault. Они добавлены в качестве параметров приложения для простоты в этом случае.
После добавления всех параметров приложения нажмите кнопку Сохранить, а затем продолжить.
Публикация серверной службы
Затем вы развернете приложение в приложении API, чтобы сделать его доступным на всех устройствах.
Заметка
Следующие действия относятся к Visual Studio для Mac. Если вы используете Visual Studio 2019 в Windows, поток публикации будет отличаться. См. статью Публикации в Службе приложений Azure в Windows.
Измените конфигурацию с отладки на выпуск, если это еще не сделано.
Элемент управления + щелкните проект PushDemoApi, а затем выберите Опубликовать в Azure... в меню публикации.
Следуйте потоку проверки подлинности, если появится запрос на это. Используйте учетную запись, используемую в предыдущем создайте приложение API.
Выберите приложение API службы приложений Azure, созданное ранее в списке в качестве целевого объекта публикации, а затем щелкните Опубликовать.
После завершения работы мастера он публикует приложение в Azure, а затем открывает приложение. Запишите URL-адрес , если это еще не сделано. Этот URL-адрес — это серверная конечная точка, которая используется далее в этом руководстве.
Проверка опубликованного API
В Postman откройте новую вкладку, задайте для запроса PUT и введите указанный ниже адрес. Замените заполнитель базовым адресом, который вы заметили в предыдущем опубликовать серверную службу раздела.
https://<app_name>.azurewebsites.net/api/notifications/installations
Заметка
Базовый адрес должен быть в формате
https://<app_name>.azurewebsites.net/
Если вы решили выполнить аутентификацию клиентов с помощью раздела ключа API, обязательно настройте заголовки запроса, чтобы включить значение apikey.
Ключ Ценность apikey <your_api_key> Выберите параметр
необработанных длятекста, а затем выберите JSON из списка параметров форматирования, а затем добавьте некоторые заполнителисодержимое JSON :{}
Щелкните Отправить.
Заметка
Вы должны получить 422 UnprocessableEntity состояние от службы.
Выполните шаги 1–4 еще раз, но на этот раз укажите конечную точку запросов, чтобы проверить получение ответа 400 недопустимых запросов.
https://<app_name>.azurewebsites.net/api/notifications/requests
Заметка
Пока не удается протестировать API с использованием допустимых данных запроса, так как для этого потребуются сведения, относящиеся к платформе, из клиентского мобильного приложения.
Создание кроссплатформенного приложения React Native
В этом разделе описано, как создать React Native мобильное приложение, реализующее push-уведомления кроссплатформенным способом.
Он позволяет зарегистрировать и отменить регистрацию из центра уведомлений с помощью созданной серверной службы.
Оповещение отображается при указании действия и приложение находится на переднем плане. В противном случае уведомления отображаются в центре уведомлений.
Заметка
Обычно вы выполняете действия регистрации (и дерегистрации) во время соответствующего момента жизненного цикла приложения (или как часть первого запуска) без явного регистрации или отмены регистрации входных данных. Однако в этом примере потребуются явные входные данные пользователя, которые позволяют просматривать и тестировать эту функцию более легко.
Создание решения React Native
В
Terminal
обновите средства среды, необходимые для работы с React Native с помощью следующих команд:# install node brew install node # or update brew update node # install watchman brew install watchman # or update brew upgrade watchman # install cocoapods sudo gem install cocoapods
В
Terminal
выполните следующую команду, если вы установили интерфейс командной строкиReact Native
, чтобы удалить ее. Используйтеnpx
для автоматического доступа к последней версии React Native CLI:npm uninstall -g react-native-cli
Заметка
React Native имеет встроенный интерфейс командной строки. Вместо того чтобы устанавливать и управлять определенной версией интерфейса командной строки глобально, рекомендуется получить доступ к текущей версии во время выполнения с помощью
npx
, которая поставляется с Node.js. Приnpx react-native <command>
текущая стабильная версия интерфейса командной строки будет загружена и выполнена во время выполнения команды.Перейдите в папку проектов, в которой вы хотите создать новое приложение. Используйте шаблон на основе Typescript, указав параметр
--template
:# init new project with npx npx react-native init PushDemo --template react-native-template-typescript
Запустите сервер метро, который создает пакеты JavaScript и отслеживает обновления кода для обновления пакетов в режиме реального времени:
cd PushDemo npx react-native start
Запустите приложение iOS, чтобы проверить настройку. Перед выполнением следующей команды убедитесь, что вы запустили симулятор iOS или подключили устройство iOS:
npx react-native run-ios
Запустите приложение Android, чтобы проверить настройку. Для этого требуется несколько дополнительных действий по настройке эмулятора Или устройства Android для доступа к серверу метро React Native. Следующие команды создают начальный пакет JavaScript для Android и помещают его в папку ресурсов.
# create assets folder for the bundle mkdir android/app/scr/main/assets # build the bundle npx react-native bundle --platform android --dev true --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res # enable ability for sim to access the localhost adb reverse tcp:8081 tcp:8081
Этот скрипт будет предварительно развернут с исходной версией приложения. После развертывания настройте эмулятор или устройство для доступа к серверу метро, указав IP-адрес сервера. Выполните следующую команду, чтобы создать и запустить приложение Android:
npx react-native run-android
После перехода в приложение нажмите
CMD+M
(эмулятор) или встряхните устройство, чтобы заполнить параметры разработчика, перейдите кSettings
>Change Bundle Location
и укажите IP-адрес сервера метро с портом по умолчанию:<metro-server-ip-address>:8081
.В файле
App.tsx
примените любое изменение к макету страницы, сохраните его и внесите изменения автоматически в приложениях iOS и Android.
Установка необходимых пакетов
Для работы этого примера вам потребуется следующие три пакета:
React Native Push Notifications iOS - Project GitHub
Этот пакет был создан, когда PushNotificationIOS был разделен от ядра React Native. Пакет изначально реализует push-уведомления для iOS и предоставляет интерфейс React Native для доступа к нему. Выполните следующую команду, чтобы установить пакет:
yarn add @react-native-community/push-notification-ios
Кроссплатформенные push-уведомления React Native
Этот пакет реализует локальные и удаленные уведомления в iOS и Android кроссплатформенным способом. Выполните следующую команду, чтобы установить пакет:
yarn add react-native-push-notification
пакет сведений об устройстве Пакет предоставляет сведения об устройстве во время выполнения. Используйте его для определения идентификатора устройства, который используется для регистрации для push-уведомлений. Выполните следующую команду, чтобы установить пакет:
yarn add react-native-device-info
Реализация кроссплатформенных компонентов
Создание и реализация
DemoNotificationHandler
:import PushNotification from 'react-native-push-notification'; class DemoNotificationHandler { private _onRegister: any; private _onNotification: any; onNotification(notification: any) { console.log('NotificationHandler:', notification); if (typeof this._onNotification === 'function') { this._onNotification(notification); } } onRegister(token: any) { console.log('NotificationHandler:', token); if (typeof this._onRegister === 'function') { this._onRegister(token); } } attachTokenReceived(handler: any) { this._onRegister = handler; } attachNotificationReceived(handler: any) { this._onNotification = handler; } } const handler = new DemoNotificationHandler(); PushNotification.configure({ onRegister: handler.onRegister.bind(handler), onNotification: handler.onNotification.bind(handler), permissions: { alert: true, badge: true, sound: true, }, popInitialNotification: true, requestPermissions: true, }); export default handler;
Создание и реализация
DemoNotificationService
:import PushNotification from 'react-native-push-notification'; import DemoNotificationHandler from './DemoNotificationHandler'; export default class DemoNotificationService { constructor(onTokenReceived: any, onNotificationReceived: any) { DemoNotificationHandler.attachTokenReceived(onTokenReceived); DemoNotificationHandler.attachNotificationReceived(onNotificationReceived); PushNotification.getApplicationIconBadgeNumber(function(number: number) { if(number > 0) { PushNotification.setApplicationIconBadgeNumber(0); } }); } checkPermissions(cbk: any) { return PushNotification.checkPermissions(cbk); } requestPermissions() { return PushNotification.requestPermissions(); } cancelNotifications() { PushNotification.cancelLocalNotifications(); } cancelAll() { PushNotification.cancelAllLocalNotifications(); } abandonPermissions() { PushNotification.abandonPermissions(); } }
Создание и реализация
DemoNotificationRegistrationService
:export default class DemoNotificationService { constructor( readonly apiUrl: string, readonly apiKey: string) { } async registerAsync(request: any): Promise<Response> { const method = 'PUT'; const registerApiUrl = `${this.apiUrl}/notifications/installations`; const result = await fetch(registerApiUrl, { method: method, headers: { Accept: 'application/json', 'Content-Type': 'application/json', 'apiKey': this.apiKey }, body: JSON.stringify(request) }); this.validateResponse(registerApiUrl, method, request, result); return result; } async deregisterAsync(deviceId: string): Promise<Response> { const method = 'DELETE'; const deregisterApiUrl = `${this.apiUrl}/notifications/installations/${deviceId}`; const result = await fetch(deregisterApiUrl, { method: method, headers: { Accept: 'application/json', 'Content-Type': 'application/json', 'apiKey': this.apiKey } }); this.validateResponse(deregisterApiUrl, method, null, result); return result; } private validateResponse(requestUrl: string, method: string, requestPayload: any, response: Response) { console.log(`Request: ${method} ${requestUrl} => ${JSON.stringify(requestPayload)}\nResponse: ${response.status}`); if (!response || response.status != 200) { throw `HTTP error ${response.status}: ${response.statusText}`; } } }
Настройте приложение. Откройте
package.json
и добавьте следующее определение скрипта:"configure": "cp .app.config.tsx src/config/AppConfig.tsx"
Затем выполните этот скрипт, который скопировать конфигурацию по умолчанию в папку
config
.yarn configure
Последним шагом является обновление файла конфигурации, скопированного на предыдущем шаге, с информацией о доступе к API. Укажите параметры
apiKey
иapiUrl
:module.exports = { appName: "PushDemo", env: "production", apiUrl: "https://<azure-push-notifications-api-url>/api/", apiKey: "<api-auth-key>", };
Реализация кроссплатформенного пользовательского интерфейса
Определение макета страницы
<View style={styles.container}> {this.state.isBusy && <ActivityIndicator></ActivityIndicator> } <View style={styles.button}> <Button title="Register" onPress={this.onRegisterButtonPress.bind(this)} disabled={this.state.isBusy} /> </View> <View style={styles.button}> <Button title="Deregister" onPress={this.onDeregisterButtonPress.bind(this)} disabled={this.state.isBusy} /> </View> </View>
Применение стилей
const styles = StyleSheet.create({ container: { flex: 1, alignItems: "center", justifyContent: 'flex-end', margin: 50, }, button: { margin: 5, width: "100%", } });
Инициализация компонента страницы
state: IState; notificationService: DemoNotificationService; notificationRegistrationService: DemoNotificationRegistrationService; deviceId: string; constructor(props: any) { super(props); this.deviceId = DeviceInfo.getUniqueId(); this.state = { status: "Push notifications registration status is unknown", registeredOS: "", registeredToken: "", isRegistered: false, isBusy: false, }; this.notificationService = new DemoNotificationService( this.onTokenReceived.bind(this), this.onNotificationReceived.bind(this), ); this.notificationRegistrationService = new DemoNotificationRegistrationService( Config.apiUrl, Config.apiKey, ); }
Определение обработчиков нажатия кнопки
async onRegisterButtonPress() { if (!this.state.registeredToken || !this.state.registeredOS) { Alert.alert("The push notifications token wasn't received."); return; } let status: string = "Registering..."; let isRegistered = this.state.isRegistered; try { this.setState({ isBusy: true, status }); const pnPlatform = this.state.registeredOS == "ios" ? "apns" : "fcm"; const pnToken = this.state.registeredToken; const request = { installationId: this.deviceId, platform: pnPlatform, pushChannel: pnToken, tags: [] }; const response = await this.notificationRegistrationService.registerAsync(request); status = `Registered for ${this.state.registeredOS} push notifications`; isRegistered = true; } catch (e) { status = `Registration failed: ${e}`; } finally { this.setState({ isBusy: false, status, isRegistered }); } } async onDeregisterButtonPress() { if (!this.notificationService) return; let status: string = "Deregistering..."; let isRegistered = this.state.isRegistered; try { this.setState({ isBusy: true, status }); await this.notificationRegistrationService.deregisterAsync(this.deviceId); status = "Deregistered from push notifications"; isRegistered = false; } catch (e) { status = `Deregistration failed: ${e}`; } finally { this.setState({ isBusy: false, status, isRegistered }); } }
Обработка регистраций полученных маркеров и push-уведомлений
onTokenReceived(token: any) { console.log(`Received a notification token on ${token.os}`); this.setState({ registeredToken: token.token, registeredOS: token.os, status: `The push notifications token has been received.` }); if (this.state.isRegistered && this.state.registeredToken && this.state.registeredOS) { this.onRegisterButtonPress(); } } onNotificationReceived(notification: any) { console.log(`Received a push notification on ${this.state.registeredOS}`); this.setState({ status: `Received a push notification...` }); if (notification.data.message) { Alert.alert(AppConfig.appName, `${notification.data.action} action received`); } } };
Настройка собственного проекта Android для push-уведомлений
Настройка необходимых пакетов Android
Пакет автоматически связан при создании приложения. Чтобы завершить процесс настройки, выполните несколько дополнительных действий.
Настройка манифеста Android
В приложении android/app/src/main/AndroidManifest.xml", проверьте имя пакета, разрешения и необходимые службы. Убедитесь, что вы зарегистрировали RNPushNotificationPublisher
и RNPushNotificationBootEventReceiver
приемников и зарегистрировали службу RNPushNotificationListenerService
. Метаданные уведомлений можно использовать для настройки внешнего вида push-уведомлений.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="YOUR_PACKAGE_NAME">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:name=".MainApplication"
android:label="@string/app_name"
android:usesCleartextTraffic="true"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="@style/AppTheme">
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name"
android:value="PushDemo Channel"/>
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_description"
android:value="PushDemo Channel Description"/>
<meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground"
android:value="true"/>
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color"
android:resource="@android:color/white"/>
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>
Настройка служб Google
В android/app/build.gradle зарегистрируйте службы Google:
dependencies {
...
implementation 'com.google.firebase:firebase-analytics:17.3.0'
...
}
apply plugin: 'com.google.gms.google-services'
Скопируйте файл "google-services.json", скачанный во время настройки FCM, в папку проекта "android/app/".
Обработка push-уведомлений для Android
Вы настроили существующую службу RNPushNotificationListenerService
для обработки входящих push-уведомлений Android. Эта служба была зарегистрирована ранее в манифесте приложения. Он обрабатывает входящие уведомления и прокси-серверы для кроссплатформенной части React Native. Никаких дополнительных шагов не требуется.
Настройка собственного проекта iOS для push-уведомлений
Настройка необходимых пакетов iOS
Пакет автоматически связан при создании приложения. Все, что необходимо сделать, — установить собственные модули pod:
npx pod-install
Настройка Info.plist и Entitlements.plist
Перейдите в папку PushDemo/ios и откройте рабочую область PushDemo.xcworkspace, выберите верхний проект PushDemo и перейдите на вкладку "Подписывание & возможности".
Обновите идентификатор пакета, чтобы соответствовать значению, используемому в профиле подготовки.
Добавьте две новые возможности с помощью кнопки "+":
- Возможности фонового режима и тиковые удаленные уведомления.
- Возможность push-уведомлений
Обработка push-уведомлений для iOS
Откройте AppDelegate.h и добавьте следующий импорт:
#import <UserNotifications/UNUserNotificationCenter.h>
Обновление списка протоколов, поддерживаемых AppDelegate, путем добавления
UNUserNotificationCenterDelegate
:@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>
Откройте AppDelegate.m и настройте все необходимые обратные вызовы iOS:
#import <UserNotifications/UserNotifications.h> #import <RNCPushNotificationIOS.h> ... // Required to register for notifications - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { [RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings]; } // Required for the register event. - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } // Required for the notification event. You must call the completion handler after handling the remote notification. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; } // Required for the registrationError event. - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error]; } // IOS 10+ Required for localNotification event - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler { [RNCPushNotificationIOS didReceiveNotificationResponse:response]; completionHandler(); } // IOS 4-10 Required for the localNotification event. - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { [RNCPushNotificationIOS didReceiveLocalNotification:notification]; } //Called when a notification is delivered to a foreground app. -(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge); }
Тестирование решения
Теперь вы можете протестировать отправку уведомлений через серверную службу.
Отправка тестового уведомления
Откройте новую вкладку в Postman.
Задайте для запроса POSTи введите следующий адрес:
https://<app_name>.azurewebsites.net/api/notifications/requests
Если вы решили выполнить аутентификацию клиентов с помощью раздела ключа API, обязательно настройте заголовки запроса, чтобы включить значение apikey.
Ключ Ценность apikey <your_api_key> Выберите параметр
необработанных длятекста, а затем выберите JSON из списка параметров форматирования, а затем добавьте некоторые заполнителисодержимое JSON :{ "text": "Message from Postman!", "action": "action_a" }
Нажмите кнопку код, которая находится под кнопкой Сохранить в правом верхнем углу окна. Запрос должен выглядеть примерно так, как показано в следующем примере при отображении
HTML- (в зависимости от того, включен ли заголовок apikey). POST /api/notifications/requests HTTP/1.1 Host: https://<app_name>.azurewebsites.net apikey: <your_api_key> Content-Type: application/json { "text": "Message from backend service", "action": "action_a" }
Запустите приложение pushDemo
на одной или обеих целевых платформах ( Android иiOS ).Заметка
Если вы тестируете Android убедитесь, что вы не работаете в отладкеили если приложение было развернуто, запустив приложение, принудительно закройте приложение и запустите его снова с средства запуска.
В приложении PushDemo нажмите кнопку Зарегистрировать.
Вернитесь в Postman, закройте окно создания фрагментов кода (если это еще не сделано), а затем нажмите кнопку Отправить.
Убедитесь, что вы получите ответ
200 OK в , а оповещение отображается в приложении сPostman действие ActionA, полученное .Закройте приложение pushDemo
, а затем нажмите кнопку Отправить еще раз в .Postman Убедитесь, что вы получите ответ 200 OK в Postman еще раз. Убедитесь, что уведомление отображается в области уведомлений для приложения PushDemo с правильным сообщением.
Коснитесь уведомления, чтобы убедиться, что оно открывает приложение и отображает действие ActionA, полученное оповещение.
В Postmanизмените текст предыдущего запроса, чтобы отправить автоматическое уведомление, указывающее action_b вместо action_a для значения действия.
{ "action": "action_b", "silent": true }
При открытии приложения нажмите кнопку Отправить в Postman.
Убедитесь, что в
появитPostman ся ответ , полученное.ОК 200 ОК, а недействие ActionA Закройте приложение pushDemo
, а затем нажмите кнопку Отправить еще раз в .Postman Убедитесь, что вы получите ответ 200 ОК в Postman и что автоматическое уведомление не отображается в области уведомлений.
Устранение неполадок
Нет ответа от серверной службы
При локальном тестировании убедитесь, что серверная служба запущена и использует правильный порт.
Если тестирование на приложения API Azure, проверьте, запущена ли служба и была развернута и запущена без ошибок.
Убедитесь, что вы правильно указали базовый адрес в Postman или в конфигурации мобильного приложения при тестировании через клиент. Базовый адрес должен быть https://<api_name>.azurewebsites.net/
или https://localhost:5001/
при локальном тестировании.
Не получая уведомления в Android после запуска или остановки сеанса отладки
Убедитесь, что вы снова зарегистрируетесь после запуска или остановки сеанса отладки. Отладчик приведет к созданию нового маркера Firebase. Также необходимо обновить установку центра уведомлений.
Получение кода состояния 401 из серверной службы
Убедитесь, что вы задаете заголовок запроса apikey
Если при локальном тестировании эта ошибка возникает, убедитесь, что значение ключа, определенное в конфигурации клиента, соответствует значению
Если вы тестируетеприложения API
Заметка
Если вы создали или изменили этот параметр после развертывания серверной службы, необходимо перезапустить службу, чтобы она вступила в силу.
Если вы решили не выполнять проверку подлинности клиентов
Получение кода состояния 404 из серверной службы
Убедитесь, что конечная точка и метод HTTP-запроса верны. Например, конечные точки должны быть примерно следующими:
-
[PUT]
https://<api_name>.azurewebsites.net/api/notifications/installations
-
[DELETE]
https://<api_name>.azurewebsites.net/api/notifications/installations/<installation_id>
-
[POST]
https://<api_name>.azurewebsites.net/api/notifications/requests
Или при локальном тестировании:
-
[PUT]
https://localhost:5001/api/notifications/installations
-
[DELETE]
https://localhost:5001/api/notifications/installations/<installation_id>
-
[POST]
https://localhost:5001/api/notifications/requests
При указании базового адреса в клиентском приложении убедитесь, что он заканчивается /
. Базовый адрес должен быть https://<api_name>.azurewebsites.net/
или https://localhost:5001/
при локальном тестировании.
Не удается зарегистрировать и отображается сообщение об ошибке центра уведомлений
Убедитесь, что тестовое устройство имеет сетевое подключение. Затем определите код состояния ответа Http, задав точку останова, чтобы проверить значение свойства StatusCode
Ознакомьтесь с предыдущими предложениями по устранению неполадок, применимыми в зависимости от кода состояния.
Задайте точку останова в строках, возвращающих эти определенные коды состояния для соответствующего API. Затем попробуйте вызвать серверную службу при локальной отладке.
Убедитесь, что серверная служба работает должным образом с помощью Postman с помощью соответствующей полезных данных. Используйте фактические полезные данные, созданные клиентским кодом для платформы.
Просмотрите разделы конфигурации для конкретной платформы, чтобы убедиться, что никаких шагов не было пропущено. Убедитесь, что подходящие значения разрешаются для installation id
и token
переменных для соответствующей платформы.
Не удается устранить идентификатор сообщения об ошибке устройства
Просмотрите разделы конфигурации для конкретной платформы, чтобы убедиться, что никаких шагов не было пропущено.
Связанные ссылки
- Обзор Центров уведомлений Azure
- установка Visual Studio для Mac
- установка Visual Studio Code
- настройка среды разработки React Native
- пакет SDK Центров уведомлений для внутренних операций
- пакет SDK для центров уведомлений на сайте GitHub
- Регистрация с помощью серверной части приложения
- управления регистрацией
- Работа с тегами
- Работа с пользовательскими шаблонами
Дальнейшие действия
Теперь вы должны иметь базовое приложение React Native, подключенное к центру уведомлений через серверную службу, и может отправлять и получать уведомления.
Скорее всего, вам потребуется адаптировать пример, используемый в этом руководстве, чтобы соответствовать собственному сценарию. Кроме того, рекомендуется реализовать более надежную обработку ошибок, логику повторных попыток и ведение журнала.
Центра приложений Visual Studio можно быстро включить в мобильные приложения, предоставляющие аналитику и диагностику для устранения неполадок.