Tutorial: Enviar notificações por push para aplicativos React Native usando Hubs de Notificação do Azure por meio de um serviço de back-end
Neste tutorial, você usará os Hubs de Notificação do Azure para enviar notificações por push para um aplicativo React Native direcionado para Android e iOS.
Um back-end da API Web ASP.NET Core é usado para lidar com o registro de dispositivo para o cliente usando a abordagem de instalação mais recente e melhor. O serviço também enviará notificações por push de maneira multiplataforma.
Essas operações são tratadas usando o SDK dos Hubs de Notificação para operações de back-end. Mais detalhes sobre a abordagem geral são fornecidos na documentação Registrar-se no back-end do aplicativo .
Este tutorial leva você pelas seguintes etapas:
- Configure os Serviços de Notificação por Push e os Hubs de Notificação do Azure.
- Crie um aplicativo de back-end da API Web ASP.NET Core.
- Crie um aplicativo de React Native multiplataforma.
- Configure o projeto nativo do Android para notificações por push.
- Configure o projeto nativo do iOS para notificações por push.
- Teste a solução.
Pré-requisitos
Para acompanhar, você precisa:
- Uma assinatura do Azure em que você pode criar e gerenciar recursos.
- Um Mac com Visual Studio para Mac instalado (ou um computador executando o Visual Studio 2019 com a carga de trabalho Desenvolvimento Móvel com .NET).
- A capacidade de executar o aplicativo em dispositivos Android (físicos ou emuladores) ou iOS (somente dispositivos físicos).
Para Android, você deve ter:
- Um dispositivo físico desbloqueado pelo desenvolvedor ou um emulador (executando a API 26 e superior com o Google Play Services instalado).
Para iOS, você deve ter:
- Uma conta de desenvolvedor ativa da Apple.
- Um dispositivo iOS físico registrado em sua conta de desenvolvedor(executando o iOS 13.0 e superior).
- Um certificado de desenvolvimento.p12 instalado em seu keychain permitindo que você execute um aplicativo em um dispositivo físico.
Observação
O Simulador do iOS não dá suporte a notificações remotas e, portanto, um dispositivo físico é necessário ao explorar este exemplo no iOS. No entanto, você não precisa executar o aplicativo no Android e no iOS para concluir este tutorial.
Você pode seguir as etapas neste exemplo de primeiros princípios sem nenhuma experiência anterior. No entanto, você se beneficiará de ter familiaridade com os aspectos a seguir.
- Portal do Desenvolvedor da Apple
- ASP.NET Core
- Google Firebase Console
- Microsoft Azure e Enviar notificações por push para aplicativos iOS usando Hubs de Notificação do Azure.
- React Native.
As etapas fornecidas são para Visual Studio para Mac e Visual Studio Code, mas é possível acompanhar usando o Visual Studio 2019.
Configurar os Serviços de Notificação por Push e o Hub de Notificação do Azure
Nesta seção, você configurará o Firebase Cloud Messaging (FCM) e o APNS (Serviços de Notificação por Push) da Apple. Em seguida, você cria e configura um hub de notificação para trabalhar com esses serviços.
Criar um projeto do Firebase e habilitar o Firebase Cloud Messaging para Android
Entre no console do Firebase. Crie um novo projeto do Firebase inserindo PushDemo como o nome do projeto.
Observação
Um nome exclusivo será gerado para você. Por padrão, isso é composto por uma variante minúscula do nome que você forneceu mais um número gerado separado por um traço. Você pode alterar isso se desejar, desde que ainda seja globalmente exclusivo.
Depois de criar seu projeto, selecione Adicionar Firebase ao seu aplicativo Android.
Na página Adicionar o Firebase ao aplicativo Android , execute as etapas a seguir.
Para o nome do pacote do Android, insira um nome para o pacote. Por exemplo:
com.<organization_identifier>.<package_name>
.Selecione Registrar aplicativo.
Selecione Baixar google-services.json. Em seguida, salve o arquivo em uma pasta local para uso posteriormente e selecione Avançar.
Selecione Avançar.
Selecione Continuar no console
Observação
Se o botão Continuar no console não estiver habilitado, devido à marcar de instalação de verificação, escolha Ignorar esta etapa.
No console do Firebase, selecione a engrenagem do projeto. Em seguida, selecione Configurações do Projeto.
Observação
Se você não tiver baixado o arquivo google-services.json , poderá baixá-lo nesta página.
Alterne para a guia Mensagens na Nuvem na parte superior. Copie e salve a chave do servidor para uso posterior. Use esse valor para configurar o hub de notificação.
Registrar seu aplicativo iOS para notificações por push
Para enviar notificações por push para um aplicativo iOS, registre seu aplicativo com a Apple e também registre-se para notificações por push.
Se você ainda não registrou seu aplicativo, navegue até o Portal de Provisionamento do iOS no Apple Developer Center. Entre no portal com sua ID da Apple, navegue até Certificados, Identificadores & Perfis e selecione Identificadores. Clique + para registrar um novo aplicativo.
Na tela Registrar um Novo Identificador , selecione o botão de opção IDs do aplicativo. Em seguida, selecione Continuar.
Atualize os três valores a seguir para seu novo aplicativo e selecione Continuar:
Descrição: digite um nome descritivo para seu aplicativo.
ID do pacote: insira uma ID de pacote do formulário com.organization_identifier<.<>>product_name conforme mencionado no Guia de Distribuição de Aplicativos. Na captura de tela a seguir, o
mobcat
valor é usado como um identificador da organização e o valor PushDemo é usado como o nome do produto.Notificações por push: verifique a opção Notificações por Push na seção Funcionalidades .
Essa ação gera sua ID do aplicativo e solicita que você confirme as informações. Selecione Continuar e, em seguida, selecione Registrar para confirmar a nova ID do Aplicativo.
Depois de selecionar Registrar, você verá a nova ID do Aplicativo como um item de linha na página Certificados, Identificadores & Perfis .
Na página Certificados, Identificadores & Perfis , em Identificadores, localize o item de linha ID do Aplicativo que você criou. Em seguida, selecione sua linha para exibir a tela Editar sua Configuração de ID do Aplicativo .
Criando um certificado para Hubs de Notificação
Um certificado é necessário para permitir que o hub de notificação funcione com o APNS (Serviços de Notificação por Push) da Apple e pode ser fornecido de duas maneiras:
Criando um certificado push p12 que pode ser carregado diretamente no Hub de Notificação (a abordagem original)
Criando um certificado p8 que pode ser usado para autenticação baseada em token (a abordagem mais recente e recomendada)
A abordagem mais recente tem uma série de benefícios, conforme documentado na autenticação baseada em token (HTTP/2) para APNS. Menos etapas são necessárias, mas também são obrigatórias para cenários específicos. No entanto, foram fornecidas etapas para ambas as abordagens, pois ambas funcionarão para fins deste tutorial.
OPTION 1: Criando um certificado push p12 que pode ser carregado diretamente no Hub de Notificação
Em seu Mac, execute a ferramenta acesso ao conjunto de chaves. Ele pode ser aberto na pasta Utilitários ou na pasta Outros na Barra Inicial.
Selecione Acesso ao Conjunto de Chaves, expanda Assistente de Certificado e, em seguida, selecione Solicitar um Certificado de uma Autoridade de Certificação.
Observação
Por padrão, o Acesso ao Conjunto de Chaves seleciona o primeiro item da lista. Isso pode ser um problema se você estiver na categoria Certificados e a Apple Worldwide Developer Relations Certification Authority não for o primeiro item na lista. Verifique se você tem um item não chave ou se a chave da Autoridade de Certificação de Relações do Desenvolvedor Mundial da Apple está selecionada antes de gerar a CSR (Solicitação de Assinatura de Certificado).
Selecione seu Endereço Email de Usuário, insira o valor nome comum, especifique Salvo em disco e selecione Continuar. Deixe CA Email Endereço em branco, pois ele não é necessário.
Insira um nome para o arquivo CSR (Solicitação de Assinatura de Certificado) em Salvar como, selecione o local em Onde e, em seguida, selecione Salvar.
Essa ação salva o arquivo CSR no local selecionado. O local padrão é Área de Trabalho. Lembre-se do local escolhido para o arquivo.
De volta à página Certificados, Identificadores & Perfis no Portal de Provisionamento do iOS, role para baixo até a opção Notificações por Push marcadas e selecione Configurar para criar o certificado.
A janela Certificados TLS/SSL do serviço de Notificação por Push da Apple é exibida. Selecione o botão Criar Certificado na seção Certificado TLS/SSL de Desenvolvimento .
A tela Criar um novo Certificado é exibida.
Observação
Este tutorial usa um certificado de desenvolvimento. O mesmo processo é usado ao registrar um certificado de produção. Apenas certifique-se de usar o mesmo tipo de certificado ao enviar notificações.
Selecione Escolher Arquivo, navegue até o local onde você salvou o arquivo CSR e clique duas vezes no nome do certificado para carregá-lo. Em seguida, selecione Continuar.
Depois que o portal criar o certificado, selecione o botão Baixar . Salve o certificado e lembre-se do local em que ele foi salvo.
O certificado é baixado e salvo no computador na pasta Downloads .
Observação
Por padrão, o certificado de desenvolvimento baixado é nomeado aps_development.cer.
Clique duas vezes no aps_development.cer de certificado por push baixado. Essa ação instala o novo certificado no conjunto de chaves, conforme mostrado na imagem a seguir:
Observação
Embora o nome em seu certificado possa ser diferente, o nome será prefixado com o Apple Development iOS Push Services e terá o identificador de pacote apropriado associado a ele.
No Acesso ao Conjunto de Chaves, Controle + Clique no novo certificado push que você criou na categoria Certificados . Selecione Exportar, nomeie o arquivo, selecione o formato p12 e, em seguida, selecione Salvar.
Você pode optar por proteger o certificado com uma senha, mas uma senha é opcional. Clique em OK se quiser ignorar a criação de senha. Anote o nome do arquivo e o local do certificado p12 exportado. Eles são usados para habilitar a autenticação com APNs.
Observação
O nome e a localização do arquivo p12 podem ser diferentes do que é retratado neste tutorial.
OPTION 2: Criando um certificado p8 que pode ser usado para autenticação baseada em token
Anote os seguintes detalhes:
- Prefixo da ID do aplicativo (ID da equipe)
- ID do pacote
De volta a Certificados, Identificadores & Perfis, clique em Chaves.
Observação
Se você já tiver uma chave configurada para APNS, poderá reutilização do certificado p8 baixado logo após sua criação. Nesse caso, você pode ignorar as etapas 3 a 5.
Clique no + botão (ou no botão Criar uma chave ) para criar uma nova chave.
Forneça um valor de Nome de Chave adequado e, em seguida, marcar a opção APNS (apple push notifications service) e clique em Continuar, seguido por Registrar na próxima tela.
Clique em Baixar e mova o arquivo p8 (prefixado com AuthKey_) para um diretório local seguro e clique em Concluído.
Observação
Certifique-se de manter o arquivo p8 em um local seguro (e salvar um backup). Depois de baixar a chave, ela não pode ser baixada novamente, pois a cópia do servidor é removida.
Em Chaves, clique na chave que você criou (ou em uma chave existente se tiver optado por usá-la).
Anote o valor da ID da chave .
Abra o certificado p8 em uma aplicação adequada de sua escolha, como Visual Studio Code. Anote o valor da chave (entre -----BEGIN PRIVATE KEY----- e -----END PRIVATE KEY-----).
CHAVE PRIVADA -----BEGIN-----
<key_value>
-----END PRIVATE KEY-----Observação
Esse é o valor do token que será usado posteriormente para configurar o Hub de Notificação.
Ao final dessas etapas, você deve ter as seguintes informações para uso posteriormente em Configurar o hub de notificação com informações de APNS:
- ID da equipe (consulte a etapa 1)
- ID do pacote (consulte a etapa 1)
- ID da chave (consulte a etapa 7)
- Valor do token (valor da chave p8 obtido na etapa 8)
Criar um perfil de provisionamento para o aplicativo
Retorne ao Portal de Provisionamento do iOS, selecione Certificados, Identificadores & Perfis, selecione Perfis no menu à esquerda e selecione + para criar um novo perfil. A tela Registrar um Novo Perfil de Provisionamento é exibida.
Selecione Desenvolvimento de Aplicativos iOS em Desenvolvimento como o tipo de perfil de provisionamento e, em seguida, selecione Continuar.
Em seguida, selecione a ID do aplicativo que você criou na lista suspensa ID do Aplicativo e selecione Continuar.
Na janela Selecionar certificados , selecione o certificado de desenvolvimento que você usa para assinatura de código e selecione Continuar.
Observação
Esse certificado não é o certificado push que você criou na etapa anterior. Esse é o certificado de desenvolvimento. Se um não existir, você deverá criá-lo, pois este é um pré-requisito para este tutorial. Os certificados de desenvolvedor podem ser criados no Portal do Desenvolvedor da Apple, por meio do Xcode ou no Visual Studio.
Retorne à página Certificados, Identificadores & Perfis , selecione Perfis no menu à esquerda e selecione + para criar um novo perfil. A tela Registrar um Novo Perfil de Provisionamento é exibida.
Na janela Selecionar certificados , selecione o certificado de desenvolvimento que você criou. Em seguida, selecione Continuar.
Em seguida, selecione os dispositivos a serem usados para teste e selecione Continuar.
Por fim, escolha um nome para o perfil em Nome do Perfil de Provisionamento e selecione Gerar.
Quando o novo perfil de provisionamento for criado, selecione Baixar. Lembre-se do local no qual ele foi salvo.
Navegue até o local do perfil de provisionamento e clique duas vezes nele para instalá-lo em seu computador de desenvolvimento.
Criar um Hub de Notificação
Nesta seção, você criará um hub de notificação e configurará a autenticação com o APNS. Você pode usar um certificado push p12 ou autenticação baseada em token. Se você quiser usar um hub de notificação que já criou, pule para a etapa 5.
Entre no Azure.
Clique em Criar um recurso, pesquise e escolha Hub de Notificação e clique em Criar.
Atualize os campos a seguir e clique em Criar:
DETALHES BÁSICOS
Assinatura: Escolha a Assinatura de destino na lista suspensa
Grupo de Recursos: Criar um novo Grupo de Recursos (ou escolher um existente)DETALHES DO NAMESPACE
Namespace do Hub de Notificação: Insira um nome globalmente exclusivo para o namespace do Hub de Notificação
Observação
Verifique se a opção Criar novo está selecionada para este campo.
DETALHES DO HUB DE NOTIFICAÇÃO
Hub de Notificação: Insira um nome para o Hub de Notificação
Localização: Escolha um local adequado na lista suspensa
Tipo de preço: Manter a opção gratuita padrãoObservação
A menos que você tenha atingido o número máximo de hubs na camada gratuita.
Depois que o Hub de Notificação tiver sido provisionado, navegue até esse recurso.
Navegue até o novo Hub de Notificação.
Selecione Políticas de Acesso na lista (em GERENCIAR).
Anote os valores de Nome da Política junto com seus valores de Cadeia de Conexão correspondentes.
Configurar o Hub de Notificação com informações de APNS
Em Serviços de Notificação, selecione Apple e siga as etapas apropriadas com base na abordagem escolhida anteriormente na seção Criando um certificado para hubs de notificação .
Observação
Use a Produção para o Modo de Aplicativo somente se você quiser enviar notificações por push aos usuários que compraram seu aplicativo da loja.
OPTION 1: Usando um certificado push .p12
Selecione Certificado.
Selecione o ícone de arquivo.
Selecione o arquivo .p12 exportado anteriormente e, em seguida, selecione Abrir.
Se necessário, especifique a senha correta.
Selecione Modo de área restrita .
Clique em Salvar.
OPTION 2: Usando a autenticação baseada em token
Selecione Token.
Insira os seguintes valores adquiridos anteriormente:
- ID da chave
- ID do pacote
- ID da equipe
- Token
Escolha Área Restrita.
Clique em Salvar.
Configurar o hub de notificação com informações de FCM
- Selecione Google (GCM/FCM) na seção Configurações no menu à esquerda.
- Insira a chave do servidor anotada no Console do Google Firebase.
- Selecione Salvar na barra de ferramentas.
Criar um aplicativo de back-end da API Web ASP.NET Core
Nesta seção, você criará o back-end da API Web ASP.NET Core para lidar com o registro do dispositivo e o envio de notificações para o aplicativo móvel React Native.
Criar um projeto Web
No Visual Studio, selecione Arquivo>Nova Solução.
SelecioneAplicativo>.NET Core>ASP.NET Core>API>Avançar.
Na caixa de diálogo Configurar sua nova API Web ASP.NET Core, selecioneEstrutura de Destino do .NET Core 3.1.
Insira PushDemoApi para o Nome do Projeto e selecione Criar.
Inicie a depuração (Command + Enter) para testar o aplicativo modelo.
Observação
O aplicativo modelo está configurado para usar o WeatherForecastController como launchUrl. Isso é definido em Propriedades>launchSettings.json.
Se você for solicitado com uma mensagem De certificado de desenvolvimento inválido encontrado :
Clique em Sim para concordar em executar a ferramenta "dotnet dev-certs https" para corrigir isso. A ferramenta "dotnet dev-certs https" solicita que você insira uma senha para o certificado e a senha do conjunto de chaves.
Clique em Sim quando solicitado a Instalar e confiar no novo certificado e insira a senha do conjunto de chaves.
Expanda a pasta Controladores e exclua WeatherForecastController.cs.
Excluir WeatherForecast.cs.
Configure valores de configuração local usando a ferramenta Gerenciador de Segredos. A desacoplamento dos segredos da solução garante que eles não acabem no controle do código-fonte. Abra o Terminal e vá para o diretório do arquivo de projeto e execute os seguintes comandos:
dotnet user-secrets init dotnet user-secrets set "NotificationHub:Name" <value> dotnet user-secrets set "NotificationHub:ConnectionString" <value>
Substitua os valores de espaço reservado por seu próprio nome de hub de notificação e valores de cadeia de conexão. Você fez uma anotação deles na seção Criar um hub de notificação . Caso contrário, você pode procurá-los no Azure.
NotificationHub:Name:
Consulte Nome no resumo do Essentials na parte superior da Visão geral.NotificationHub:ConnectionString:
Confira DefaultFullSharedAccessSignature em Políticas de AcessoObservação
Para cenários de produção, você pode examinar opções como o Azure KeyVault para armazenar com segurança o cadeia de conexão. Para simplificar, os segredos serão adicionados às configurações do aplicativo Serviço de Aplicativo do Azure.
Autenticar clientes usando uma chave de API (opcional)
As chaves de API não são tão seguras quanto os tokens, mas serão suficientes para os fins deste tutorial. Uma chave de API pode ser configurada facilmente por meio do middleware ASP.NET.
Adicione a chave de API aos valores de configuração local.
dotnet user-secrets set "Authentication:ApiKey" <value>
Observação
Você deve substituir o valor do espaço reservado pelo seu próprio e anote-o.
Controle + Clique no projeto PushDemoApi , escolha Nova Pasta no menu Adicionar e, em seguida, clique em Adicionar usando Autenticação como o Nome da Pasta.
Controle + Clique na pasta Autenticação e escolha Novo Arquivo... no menu Adicionar .
SelecioneClasse VaziaGeral>, insira ApiKeyAuthOptions.cs para o Nome e clique em Novo adicionando a implementação a seguir.
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; } } }
Adicione outra Classe Vazia à pasta Autenticação chamada ApiKeyAuthHandler.cs e adicione a implementação a seguir.
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)); } } }
Observação
Um Manipulador de Autenticação é um tipo que implementa o comportamento de um esquema, nesse caso, um esquema de chave de API personalizado.
Adicione outra Classe Vazia à pasta Autenticação chamada ApiKeyAuthenticationBuilderExtensions.cs e adicione a implementação a seguir.
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); } } }
Observação
Esse método de extensão simplifica o código de configuração de middleware em Startup.cs tornando-o mais legível e geralmente mais fácil de seguir.
Em Startup.cs, atualize o método ConfigureServices para configurar a autenticação de Chave de API abaixo da chamada para os serviços. Método 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); }
Ainda em Startup.cs, atualize o método Configure para chamar os métodos de extensão UseAuthentication e UseAuthorization no IApplicationBuilder do aplicativo. Verifique se esses métodos são chamados após UseRouting e antes do aplicativo. 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(); }); }
Observação
Chamar UseAuthentication registra o middleware que usa os esquemas de autenticação registrados anteriormente (de ConfigureServices). Isso deve ser chamado antes de qualquer middleware que dependa da autenticação dos usuários.
Adicionar dependências e configurar serviços
ASP.NET Core dá suporte ao padrão de design de software de DI (injeção de dependência), que é uma técnica para alcançar a IoC (Inversão de Controle) entre classes e suas dependências.
O uso do hub de notificação e do SDK dos Hubs de Notificação para operações de back-end é encapsulado em um serviço. O serviço é registrado e disponibilizado por meio de uma abstração adequada.
Controle + Clique na pasta Dependências e escolha Gerenciar Pacotes NuGet....
Pesquise Microsoft.Azure.NotificationHubs e verifique se ele está marcado.
Clique em Adicionar Pacotes e em Aceitar quando solicitado a aceitar os termos de licença.
Controle + Clique no projeto PushDemoApi , escolha Nova Pasta no menu Adicionar e, em seguida, clique em Adicionar usando Modelos como o Nome da Pasta.
Controle + Clique na pasta Modelos e escolha Novo Arquivo... no menu Adicionar .
SelecioneClasse VaziaGeral>, insira PushTemplates.cs para o Nome e clique em Novo adicionando a implementação a seguir.
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)\" }"; } } }
Observação
Essa classe contém os conteúdos de notificação com token para as notificações genéricas e silenciosas exigidas por esse cenário. As cargas são definidas fora da Instalação para permitir a experimentação sem precisar atualizar as instalações existentes por meio do serviço. O tratamento de alterações nas instalações dessa maneira está fora do escopo deste tutorial. Para produção, considere modelos personalizados.
Adicione outra Classe Vazia à pasta Modelos chamada DeviceInstallation.cs e adicione a implementação a seguir.
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>(); } }
Adicione outra Classe Vazia à pasta Modelos chamada NotificationRequest.cs e adicione a implementação a seguir.
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; } } }
Adicione outra Classe Vazia à pasta Modelos chamada NotificationHubOptions.cs e adicione a implementação a seguir.
using System.ComponentModel.DataAnnotations; namespace PushDemoApi.Models { public class NotificationHubOptions { [Required] public string Name { get; set; } [Required] public string ConnectionString { get; set; } } }
Adicione uma nova pasta ao projeto PushDemoApi chamado Serviços.
Adicione uma Interface Vazia à pasta Serviços chamada INotificationService.cs e adicione a implementação a seguir.
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); } }
Adicione uma Classe Vazia à pasta Serviços chamada NotificationHubsService.cs e adicione o seguinte código para implementar a interface 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); } } }
Observação
A expressão de marca fornecida a SendTemplateNotificationAsync é limitada a 20 marcas. Ele é limitado a 6 para a maioria dos operadores, mas a expressão contém apenas ORs (||) nesse caso. Se houver mais de 20 marcas na solicitação, elas deverão ser divididas em várias solicitações. Consulte a documentação Expressões de Roteamento e Marca para obter mais detalhes.
Em Startup.cs, atualize o método ConfigureServices para adicionar o NotificationHubsService como uma implementação singleton de 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(); }
Criar a API de notificações
Controle + Clique na pasta Controladores e escolha Novo Arquivo... no menu Adicionar .
Selecione ASP.NET Core>Classe de Controlador de API Web, insira NotificationsController para o Nome e clique em Novo.
Observação
Se você estiver seguindo com o Visual Studio 2019, escolha o modelo Controlador de API com ações de leitura/gravação .
Adicione os namespaces a seguir à parte superior do arquivo.
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;
Atualize o controlador modelo para que ele seja derivado de ControllerBase e seja decorado com o atributo ApiController .
[ApiController] [Route("api/[controller]")] public class NotificationsController : ControllerBase { // Templated methods here }
Observação
A classe base Controller fornece suporte para exibições, mas isso não é necessário nesse caso e, portanto , ControllerBase pode ser usado. Se você estiver seguindo com o Visual Studio 2019, ignore esta etapa.
Se você optar por concluir a seção Autenticar clientes usando uma Chave de API , decore o NotificationsController com o atributo Authorize também.
[Authorize]
Atualize o construtor para aceitar a instância registrada de INotificationService como um argumento e atribua-o a um membro somente leitura.
readonly INotificationService _notificationService; public NotificationsController(INotificationService notificationService) { _notificationService = notificationService; }
Em launchSettings.json (dentro da pasta Propriedades ), altere launchUrl de
weatherforecast
para api/notifications para corresponder à URL especificada no atributo RegistrationsControllerRoute .Inicie a depuração (Command + Enter) para validar se o aplicativo está funcionando com o novo NotificationsController e retorna um 401 Status não autorizado.
Observação
O Visual Studio pode não iniciar automaticamente o aplicativo no navegador. Você usará o Postman para testar a API desse ponto em diante.
Em uma nova guia do Postman , defina a solicitação como GET. Insira o endereço abaixo substituindo o espaço reservado< applicationUrl> pelo aplicativo httpsUrl encontrado em Propriedades>launchSettings.json.
<applicationUrl>/api/notifications
Observação
O applicationUrl deve ser 'https://localhost:5001' para o perfil padrão. Se você estiver usando o IIS (padrão no Visual Studio 2019 no Windows), deverá usar o applicationUrl especificado no item iisSettings . Você receberá uma resposta 404 se o endereço estiver incorreto.
Se você optar por concluir a seção Autenticar clientes usando uma Chave de API , configure os cabeçalhos de solicitação para incluir o valor de apikey .
Chave Valor apikey <your_api_key> Clique no botão Enviar .
Observação
Você deve receber uma status 200 OK com algum conteúdo JSON.
Se você receber um aviso de verificação de certificado SSL , poderá alternar a configuração do Postman de verificação de certificado SSL de solicitação nas Configurações.
Substitua os métodos de classe com modelo em NotificationsController.cs pelo código a seguir.
[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(); }
Criar o aplicativo de API
Agora você cria um Aplicativo de API no Serviço de Aplicativo do Azure para hospedar o serviço de back-end.
Entre no portal do Azure.
Clique em Criar um recurso, pesquise e escolha Aplicativo de API e clique em Criar.
Atualize os campos a seguir e clique em Criar.
Nome do aplicativo:
Insira um nome globalmente exclusivo para o aplicativo de APIAssinatura:
Escolha a mesma Assinatura de destino na qual você criou o hub de notificação.Grupo de Recursos:
Escolha o mesmo Grupo de Recursos no qual você criou o hub de notificação.Serviço de Aplicativo Plano/Local:
Criar um novo plano de Serviço de AplicativoObservação
Altere da opção padrão para um plano que inclua suporte a SSL . Caso contrário, você precisará executar as etapas apropriadas ao trabalhar com o aplicativo móvel para impedir que as solicitações http sejam bloqueadas.
Application Insights:
Mantenha a opção sugerida (um novo recurso será criado usando esse nome) ou escolha um recurso existente.Depois que o Aplicativo de API tiver sido provisionado, navegue até esse recurso.
Anote a propriedade URL no resumo do Essentials na parte superior da Visão geral. Essa URL é o ponto de extremidade de back-end que será usado posteriormente neste tutorial.
Observação
A URL usa o nome do aplicativo de API especificado anteriormente, com o formato
https://<app_name>.azurewebsites.net
.Selecione Configuração na lista (em Configurações).
Para cada uma das configurações abaixo, clique em Nova configuração de aplicativo para inserir o Nome e um Valor e clique em OK.
Nome Valor Authentication:ApiKey
<api_key_value> NotificationHub:Name
<hub_name_value> NotificationHub:ConnectionString
<hub_connection_string_value> Observação
Essas são as mesmas configurações que você definiu anteriormente nas configurações do usuário. Você deve ser capaz de copiá-los. A configuração Authentication:ApiKey será necessária somente se você optar por concluir a seção Autenticar clientes usando uma chave de API . Para cenários de produção, você pode examinar opções como o Azure KeyVault. Elas foram adicionadas como configurações de aplicativo para simplificar nesse caso.
Depois que todas as configurações do aplicativo tiverem sido adicionadas, clique em Salvar e em Continuar.
Publicar o serviço de back-end
Em seguida, você implanta o aplicativo no Aplicativo de API para torná-lo acessível de todos os dispositivos.
Observação
As etapas a seguir são específicas para Visual Studio para Mac. Se você estiver seguindo o Visual Studio 2019 no Windows, o fluxo de publicação será diferente. Consulte Publicar no Serviço de Aplicativo do Azure no Windows.
Altere sua configuração de Depurar para Versão se você ainda não tiver feito isso.
Controle + Clique no projeto PushDemoApi e escolha Publicar no Azure... no menu Publicar .
Siga o fluxo de autenticação se solicitado a fazê-lo. Use a conta que você usou na seção anterior criar o Aplicativo de API .
Selecione o aplicativo de API Serviço de Aplicativo do Azure criado anteriormente na lista como destino de publicação e clique em Publicar.
Depois de concluir o assistente, ele publicará o aplicativo no Azure e, em seguida, abrirá o aplicativo. Anote a URL se você ainda não fez isso. Essa URL é o ponto de extremidade de back-end usado posteriormente neste tutorial.
Validando a API publicada
No Postman , abra uma nova guia, defina a solicitação como PUT e insira o endereço abaixo. Substitua o espaço reservado pelo endereço base que você anotou na seção publicar anteriormente o serviço de back-end .
https://<app_name>.azurewebsites.net/api/notifications/installations
Observação
O endereço base deve estar no formato
https://<app_name>.azurewebsites.net/
Se você optar por concluir a seção Autenticar clientes usando uma chave de API , configure os cabeçalhos de solicitação para incluir seu valor apikey .
Chave Valor apikey <your_api_key> Escolha a opção bruta para o Corpo, escolha JSON na lista de opções de formato e, em seguida, inclua algum conteúdo JSON de espaço reservado:
{}
Clique em Enviar.
Observação
Você deve receber um status 422 UnprocessableEntity do serviço.
Execute as etapas 1 a 4 novamente, mas desta vez especificando o ponto de extremidade de solicitações para validar se você recebe uma resposta 400 Solicitação Inválida .
https://<app_name>.azurewebsites.net/api/notifications/requests
Observação
Ainda não é possível testar a API usando dados de solicitação válidos, pois isso exigirá informações específicas da plataforma do aplicativo móvel cliente.
Criar um aplicativo de React Native multiplataforma
Nesta seção, você criará um aplicativo móvel React Native implementando notificações por push de maneira multiplataforma.
Ele permite que você registre e desregistre de um hub de notificação por meio do serviço de back-end que você criou.
Um alerta é exibido quando uma ação é especificada e o aplicativo está em primeiro plano. Caso contrário, as notificações aparecerão no centro de notificações.
Observação
Normalmente, você executaria as ações de registro (e desregistração) durante o ponto apropriado no ciclo de vida do aplicativo (ou como parte de sua experiência de primeira execução, talvez) sem entradas explícitas de registro/desregistro de usuário. No entanto, este exemplo exigirá uma entrada explícita do usuário para permitir que essa funcionalidade seja explorada e testada com mais facilidade.
Criar a solução React Native
No
Terminal
, atualize suas ferramentas de ambiente, necessárias para trabalhar com React Native usando os seguintes comandos:# 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
No
Terminal
, execute o comando a seguir, se você tiverReact Native
a CLI instalada para desinstalá-la. Usenpx
para acessar automaticamente a versão mais recente da CLI React Native disponível:npm uninstall -g react-native-cli
Observação
React Native tem uma interface de linha de comando interna. Em vez de instalar e gerenciar uma versão específica da CLI globalmente, recomendamos que você acesse a versão atual em runtime usando
npx
, que é fornecida com Node.js. Comnpx react-native <command>
, a versão estável atual da CLI será baixada e executada no momento em que o comando for executado.Navegue até a pasta de projetos em que deseja criar o novo aplicativo. Use o modelo baseado em Typescript especificando o
--template
parâmetro :# init new project with npx npx react-native init PushDemo --template react-native-template-typescript
Execute o metro server, que cria pacotes JavaScript e monitora todas as atualizações de código para atualizar os pacotes em tempo real:
cd PushDemo npx react-native start
Execute o aplicativo iOS para verificar a configuração. Verifique se você iniciou um simulador do iOS ou conectou um dispositivo iOS antes de executar o seguinte comando:
npx react-native run-ios
Execute o aplicativo Android para verificar a configuração. Ele requer algumas etapas adicionais para configurar um emulador ou dispositivo Android para poder acessar o servidor metro React Native. Os comandos a seguir geram o pacote JavaScript inicial para Android e o colocam na pasta de ativos.
# 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
Esse script será pré-implantado com a versão inicial do aplicativo. Depois de implantado, configure o emulador ou dispositivo para acessar o servidor metro especificando o endereço IP do servidor. Execute o seguinte comando para compilar e executar o aplicativo Android:
npx react-native run-android
Uma vez no aplicativo, pressione
CMD+M
(emulador) ou agite o dispositivo para preencher as configurações do desenvolvedor, navegue atéChange Bundle Location
Settings
> e especifique o endereço IP do servidor metro com a porta padrão: .<metro-server-ip-address>:8081
App.tsx
No arquivo, aplique qualquer alteração ao layout da página, salve-o e faça com que a alteração seja refletida automaticamente em aplicativos iOS e Android.Observação
O guia detalhado de configuração do ambiente de desenvolvimento está disponível na documentação oficial
Instalar pacotes necessários
Você precisa dos três pacotes a seguir para que este exemplo funcione:
React Native Notificações por Push do iOS - Project GitHub
Esse pacote foi criado quando o PushNotificationIOS foi dividido do núcleo de React Native. O pacote implementa nativamente notificações por push para iOS e fornece React Native interface para acessá-lo. Execute o seguinte comando para instalar o pacote:
yarn add @react-native-community/push-notification-ios
React Native notificações por push entre plataformas
Esse pacote implementa notificações locais e remotas no iOS e no Android de maneira multiplataforma. Execute o seguinte comando para instalar o pacote:
yarn add react-native-push-notification
Pacote de informações do dispositivo O pacote fornece informações sobre um dispositivo em runtime. Use-o para definir um identificador de dispositivo, que é usado para registrar para notificação por push. Execute o seguinte comando para instalar o pacote:
yarn add react-native-device-info
Implementar os componentes multiplataforma
Criar e implementar
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;
Criar e implementar
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(); } }
Criar e implementar
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}`; } } }
Configure o aplicativo. Abra
package.json
e adicione a seguinte definição de script:"configure": "cp .app.config.tsx src/config/AppConfig.tsx"
Em seguida, execute esse script, que copiará a configuração padrão para a
config
pasta .yarn configure
A etapa final é atualizar o arquivo de configuração copiado na etapa anterior com as informações de acesso à API. Especificar
apiKey
eapiUrl
parâmetros:module.exports = { appName: "PushDemo", env: "production", apiUrl: "https://<azure-push-notifications-api-url>/api/", apiKey: "<api-auth-key>", };
Implementar a interface do usuário multiplataforma
Definir layout de página
<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>
Aplicar estilos
const styles = StyleSheet.create({ container: { flex: 1, alignItems: "center", justifyContent: 'flex-end', margin: 50, }, button: { margin: 5, width: "100%", } });
Inicializar o componente de página
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, ); }
Definir manipuladores de clique de botão
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 }); } }
Manipular registros de token recebidos e notificações por 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`); } } };
Configurar o projeto nativo do Android para notificações por push
Configurar pacotes Android necessários
O pacote é vinculado automaticamente ao criar o aplicativo. Você tem algumas etapas adicionais abaixo para concluir o processo de configuração.
Configurar manifesto do Android
Em seu "android/app/src/main/AndroidManifest.xml", verifique o nome do pacote, as permissões e os serviços necessários. Verifique se você registrou RNPushNotificationPublisher
e RNPushNotificationBootEventReceiver
receptores e registrou o RNPushNotificationListenerService
serviço. Os metadados de notificações podem ser usados para personalizar sua aparência de notificações por 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>
Configurar os serviços do Google
Em "android/app/build.gradle" registre o Google Services:
dependencies {
...
implementation 'com.google.firebase:firebase-analytics:17.3.0'
...
}
apply plugin: 'com.google.gms.google-services'
Copie o arquivo "google-services.json" que você baixou durante a instalação do FCM para a pasta do projeto "android/app/".
Manipular notificações por push para Android
Você configurou o serviço existente RNPushNotificationListenerService
para lidar com as notificações por push do Android de entrada. Esse serviço foi registrado anteriormente no manifesto do aplicativo. Ele processa as notificações de entrada e as faz proxies para a parte React Native multiplataforma. Nenhuma etapa adicional é necessária.
Configurar o projeto nativo do iOS para notificações por push
Configurar pacotes iOS necessários
O pacote é vinculado automaticamente ao criar o aplicativo. Tudo o que você precisa fazer é instalar os pods nativos:
npx pod-install
Configurar Info.plist e Entitlements.plist
Vá para a pasta "PushDemo/ios" e abra o workspace "PushDemo.xcworkspace", selecione o projeto superior "PushDemo" e selecione a guia "Assinatura & Funcionalidades".
Atualize o Identificador de Pacote para corresponder ao valor usado no perfil de provisionamento.
Adicione duas novas funcionalidades usando o botão - "+":
- Funcionalidade do Modo de Tela de Fundo e notificações remotas de escala.
- Funcionalidade de Notificações por Push
Manipular notificações por push para iOS
Abra "AppDelegate.h" e adicione a seguinte importação:
#import <UserNotifications/UNUserNotificationCenter.h>
Atualize a lista de protocolos com suporte no "AppDelegate", adicionando
UNUserNotificationCenterDelegate
:@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>
Abra "AppDelegate.m" e configure todos os retornos de chamada do iOS necessários:
#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); }
Testar a solução
Agora você pode testar o envio de notificações por meio do serviço de back-end.
Enviar uma notificação de teste
Abra uma nova guia no Postman.
Defina a solicitação como POST e insira o seguinte endereço:
https://<app_name>.azurewebsites.net/api/notifications/requests
Se você optar por concluir a seção Autenticar clientes usando uma chave de API , configure os cabeçalhos de solicitação para incluir seu valor apikey .
Chave Valor apikey <your_api_key> Escolha a opção bruta para o Corpo, escolha JSON na lista de opções de formato e, em seguida, inclua algum conteúdo JSON de espaço reservado:
{ "text": "Message from Postman!", "action": "action_a" }
Selecione o botão Código , que está no botão Salvar no canto superior direito da janela. A solicitação deve ser semelhante ao exemplo a seguir quando exibida para HTML (dependendo se você incluiu um cabeçalho 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" }
Execute o aplicativo PushDemo em uma ou ambas as plataformas de destino (Android e iOS).
Observação
Se você estiver testando no Android , verifique se não está em execução na Depuração ou se o aplicativo foi implantado executando o aplicativo, force fechar o aplicativo e iniciá-lo novamente no inicializador.
No aplicativo PushDemo , toque no botão Registrar .
De volta ao Postman, feche a janela Gerar Snippets de Código (se você ainda não fez isso) e clique no botão Enviar .
Valide se você obtém uma resposta 200 OK no Postman e o alerta aparece no aplicativo mostrando a ação ActionA recebida.
Feche o aplicativo PushDemo e clique no botão Enviar novamente no Postman.
Valide se você obtém uma resposta 200 OK no Postman novamente. Valide se uma notificação aparece na área de notificação do aplicativo PushDemo com a mensagem correta.
Toque na notificação para confirmar que ele abre o aplicativo e exibiu o alerta recebido da ação ActionA .
No Postman, modifique o corpo da solicitação anterior para enviar uma notificação silenciosa especificando action_b em vez de action_a para o valor da ação .
{ "action": "action_b", "silent": true }
Com o aplicativo ainda aberto, clique no botão Enviar no Postman.
Valide se você obtém uma resposta 200 OK no Postman e se o alerta aparece no aplicativo mostrando a ação ActionB recebida em vez da ação ActionA recebida.
Feche o aplicativo PushDemo e clique no botão Enviar novamente no Postman.
Valide se você obtém uma resposta 200 OK no Postman e se a notificação silenciosa não aparece na área de notificação.
Solução de problemas
Nenhuma resposta do serviço de back-end
Ao testar localmente, verifique se o serviço de back-end está em execução e se está usando a porta correta.
Se estiver testando no Aplicativo de API do Azure, marcar o serviço está em execução e foi implantado e foi iniciado sem erro.
Certifique-se de marcar você especificou o endereço base corretamente no Postman ou na configuração do aplicativo móvel ao testar por meio do cliente. O endereço base deve ser https://<api_name>.azurewebsites.net/
indicativamente ou https://localhost:5001/
ao testar localmente.
Não receber notificações no Android depois de iniciar ou interromper uma sessão de depuração
Verifique se você se registrou novamente depois de iniciar ou interromper uma sessão de depuração. O depurador fará com que um novo token firebase seja gerado. A instalação do hub de notificação também deve ser atualizada.
Recebendo um código 401 status do serviço de back-end
Valide se você está definindo o cabeçalho de solicitação apikey e esse valor corresponde ao que você configurou para o serviço de back-end.
Se você receber esse erro ao testar localmente, verifique se o valor da chave definido na configuração do cliente corresponde ao valor de configuração de usuário Authentication:ApiKey usado pela API.
Se você estiver testando com um Aplicativo de API, verifique se o valor da chave no arquivo de configuração do cliente corresponde à configuração de aplicativo Authentication:ApiKey que você está usando no Aplicativo de API.
Observação
Se você tiver criado ou alterado essa configuração depois de implantar o serviço de back-end, deverá reiniciar o serviço para que ele entre em vigor.
Se você optar por não concluir a seção Autenticar clientes usando uma chave de API , verifique se você não aplicou o atributo Authorize à classe NotificationsController .
Recebendo um código 404 status do serviço de back-end
Valide se o ponto de extremidade e o método de solicitação HTTP estão corretos. Por exemplo, os pontos de extremidade devem ser:
- [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
Ou ao testar localmente:
- [PUT]
https://localhost:5001/api/notifications/installations
- [DELETE]
https://localhost:5001/api/notifications/installations/<installation_id>
- [POST]
https://localhost:5001/api/notifications/requests
Ao especificar o endereço base no aplicativo cliente, verifique se ele termina com um /
. O endereço base deve ser https://<api_name>.azurewebsites.net/
indicativamente ou https://localhost:5001/
ao testar localmente.
Não é possível registrar e uma mensagem de erro do hub de notificação é exibida
Verifique se o dispositivo de teste tem conectividade de rede. Em seguida, determine a resposta Http status código definindo um ponto de interrupção para inspecionar o valor da propriedade StatusCode no HttpResponse.
Examine as sugestões de solução de problemas anteriores, quando aplicável com base no código status.
Defina um ponto de interrupção nas linhas que retornam esses códigos de status específicos para a respectiva API. Em seguida, tente chamar o serviço de back-end ao depurar localmente.
Valide se o serviço de back-end está funcionando conforme o esperado por meio do Postman usando o conteúdo apropriado. Use a carga real criada pelo código do cliente para a plataforma em questão.
Examine as seções de configuração específicas da plataforma para garantir que nenhuma etapa tenha sido perdida. Verifique se os valores adequados estão sendo resolvidos para installation id
variáveis e token
para a plataforma apropriada.
Não é possível resolve uma ID para a mensagem de erro do dispositivo é exibida
Examine as seções de configuração específicas da plataforma para garantir que nenhuma etapa tenha sido perdida.
Links relacionados
- Visão geral dos Hubs de Notificação do Azure
- Instalando Visual Studio para Mac
- Instalando Visual Studio Code
- Configurando o ambiente de desenvolvimento React Native
- SDK de Hubs de Notificação para operações de back-end
- SDK de Hubs de Notificação no GitHub
- Registrar-se com o back-end do aplicativo
- Gerenciamento de registro
- Trabalhando com marcas
- Trabalhando com modelos personalizados
Próximas etapas
Agora você deve ter um aplicativo de React Native básico conectado a um hub de notificação por meio de um serviço de back-end e pode enviar e receber notificações.
Provavelmente, você precisará adaptar o exemplo usado neste tutorial para se ajustar ao seu próprio cenário. A implementação de tratamento de erros, lógica de repetição e registro em log mais robustos também é recomendada.
O Visual Studio App Center pode ser rapidamente incorporado em aplicativos móveis, fornecendo análise ediagnóstico para ajudar na solução de problemas.