Tutorial: Enviar notificações por push para aplicativos Xamarin.Forms usando os Hubs de Notificação do Azure por meio de um serviço de back-end
Neste tutorial, você usa Hubs de Notificação do Azure para enviar notificações por push para um aplicativo Xamarin.Forms direcionado Android e iOS.
Um back-end
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 no Registrando a partir do back-end do seu aplicativo documentação.
Este tutorial leva você pelas seguintes etapas:
- Configurar 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 Xamarin.Forms de plataforma cruzada.
- Configure o projeto Android nativo para notificações push.
- Configure o projeto iOS nativo para notificações por push.
- Teste a solução.
Pré-requisitos
Para acompanhar, você precisa:
- Uma assinatura do Azure onde você pode criar e gerenciar recursos.
- Um Mac com Visual Studio para Mac instalado ou um PC executando Visual Studio 2019.
os usuários do Visual Studio 2019 também devem ter o desenvolvimentoMobile com .NET e cargas de trabalho de de desenvolvimentoASP.NET e Web instaladas. - A capacidade de executar o aplicativo em Android (dispositivos físicos ou emuladores) ou iOS (apenas 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 Apple ativa.
- Um dispositivo iOS físico que está registado na sua conta de programador(com iOS 13.0 e superior).
- Um certificado de desenvolvimento de
.p12 instalado em seu porta-chavespermitindo que você execute um aplicativo em um dispositivo físico .
Observação
O simulador do iOS não suporta 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 iOS para concluir este tutorial.
Você pode seguir as etapas neste exemplo de primeiros princípios sem experiência prévia. No entanto, você se beneficiará de ter familiaridade com os seguintes aspetos.
- do Portal do Desenvolvedor da Apple
- ASP.NET Core e API Web
- Google Firebase Console
- Microsoft Azure e Enviar notificações por push para aplicativos iOS usando os Hubs de Notificação do Azure.
- Xamarin e Xamarin.Forms.
Importante
As etapas fornecidas são específicas para Visual Studio para Mac. É possível acompanhar usando do Visual Studio 2019, mas pode haver algumas diferenças para conciliar. Por exemplo, descrições da interface do usuário e fluxos de trabalho, nomes de modelos, configuração de ambiente e assim por diante.
Configurar os Serviços de Notificação por Push e o Hub de Notificação do Azure
Nesta seção, você configura do Firebase Cloud Messaging (FCM) e Apple Push Notification Services (APNS). Em seguida, você cria e configura um hub de notificação para trabalhar com esses serviços.
Criar um projeto do Firebase e ativar o Firebase Cloud Messaging para Android
Inicie sessão na consola 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 quiser, desde que ainda seja globalmente exclusivo.
Depois de criar seu projeto, selecione Adicionar Firebase ao seu aplicativo Android.
Na página Adicionar Firebase ao seu aplicativo Android, siga as etapas a seguir.
Para o nome do pacote Android, insira um nome para o pacote. Por exemplo:
com.<organization_identifier>.<package_name>
.Selecione aplicativo Registrar.
Selecione Download google-services.json. Em seguida, salve o arquivo em uma pasta local para uso posterior e selecione Avançar.
Selecione Avançar.
Selecione Continuar para o console
Observação
Se o botão
Continuar para console não estiver habilitado, devido à verificação do de instalaçãoverificação, escolha Ignorar esta etapa .
No console do Firebase, selecione a engrenagem do seu projeto. Em seguida, selecione Configurações do projeto.
Observação
Se você não baixou o arquivo google-services.json, você pode baixá-lo nesta página.
Mude para o separador
Cloud Messaging na parte superior. Copie e salve a chave do Server para uso posterior. Use esse valor para configurar seu hub de notificação.
Registre seu aplicativo iOS para notificações por push
Para enviar notificações push para uma aplicação iOS, registe a sua aplicação na Apple e registe-se também para receber notificações push.
Se você ainda não registrou seu aplicativo, navegue até o
Portal de provisionamento do iOS no Apple Developer Center. Inicie sessão no portal com o seu ID Apple, navegue até Certificados, Identificadores & Perfis e, em seguida, selecione Identificadores. Clique em + para registrar um novo aplicativo. Na tela Registrar um Novo Identificador, selecione o botão de opção IDs de aplicativo botão de opção. Em seguida, selecione Continuar.
Atualize os três valores seguintes para a sua nova aplicação e, em seguida, selecione Continuar:
Descrição: digite um nome descritivo para seu aplicativo.
ID do pacote: Insira um ID do 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 valor
mobcat
é usado como um identificador da organização e o valor PushDemo é usado como o nome do produto.de Notificações por Push: Marque a opção Notificações por Push na seção Capabilities.
Essa ação gera sua ID de aplicativo e solicita que você confirme as informações. Selecione Continuare, em seguida, selecione Registar para confirmar o novo ID da aplicação.
Depois de selecionar
Registrar , você verá a nova ID do aplicativo como um item de linha na páginaCertificados, 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 a configuração do ID do aplicativo tela.
Criando um certificado para Hubs de Notificação
Um certificado é necessário para permitir que o hub de notificação funcione com Apple Push Notification Services (APNS) e pode ser fornecido de duas maneiras:
Criando um certificado por 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 tokens (a abordagem mais recente e recomendada)
A abordagem mais recente tem uma série de benefícios, conforme documentado em autenticação baseada em token (HTTP/2) para APNS. São necessárias menos etapas, mas também é obrigatório para cenários específicos. No entanto, foram fornecidas etapas para ambas as abordagens, uma vez que ambas funcionarão para os fins deste tutorial.
OPÇÃO 1: Criando um certificado por push p12 que pode ser carregado diretamente no Hub de Notificação
No Mac, execute a ferramenta Acesso às Chaves. Ele pode ser aberto a partir da pasta Utilities ou da pasta Other na Barra Inicial.
Selecione de Acesso às Chaves, expanda Assistente de Certificadoe, em seguida, selecione Solicitar um Certificado de uma Autoridade de Certificação.
Observação
Por padrão, o Acesso às Chaves seleciona o primeiro item da lista. Isso pode ser um problema se você estiver na categoria Certificados e Autoridade de Certificação Apple Worldwide Developer Relations não for o primeiro item da lista. Certifique-se de que tem um item não chave ou que a chave Apple Worldwide Developer Relations Certification Authority está selecionada antes de gerar o CSR (Pedido de Assinatura de Certificado).
Selecione seu endereço de e-mail de usuário , insira seu nome comum valor, certifique-se de especificar Salvo em discoe, em seguida, selecione Continuar. Deixe endereço de e-mail da autoridade de certificação em branco, pois não é necessário.
Introduza um nome para o ficheiro de Pedido de Assinatura de Certificado (CSR) em Guardar Como, selecione a localização em Ondee, em seguida, selecione Guardar.
Esta ação salva a do arquivo CSR
no local selecionado. O local padrão é Desktop. Lembre-se do local escolhido para o arquivo. De volta à página
Certificados, Identificadores & Perfis na Portal de Provisionamento do iOS , role para baixo até a opção Notificações por Push do marcada e selecione Configurar para criar o certificado.A janela Apple Push Notification service TLS/SSL Certificates é exibida. Selecione o botão
Criar de Certificado na seção de Certificado TLS/SSL de Desenvolvimento. A tela Criar um novo certificado é exibida.
Observação
Este tutorial usa um certificado de desenvolvimento. O mesmo processo é utilizado no registo de 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 Download. Salve o certificado e lembre-se do local no qual ele foi salvo.
O certificado é transferido e guardado no seu computador na pasta
Downloads. Observação
Por padrão, o certificado de desenvolvimento baixado é chamado aps_development.cer.
Clique duas vezes no certificado push baixado aps_development.cer. Esta ação instala o novo certificado no Porta-chaves, conforme mostrado na imagem a seguir:
Observação
Embora o nome no seu certificado possa ser diferente, o nome será prefixado com Apple Development iOS Push Services e terá o identificador de pacote apropriado associado a ele.
Em Acesso às Chaves,
Controle Clique em no novo certificado push que você criou na categoriaCertificados. Selecione Exportar, nomeie o arquivo, selecione o formato de p12 e 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.
OPÇÃO 2: Criando um certificado p8 que pode ser usado para autenticação baseada em token
Anote os seguintes detalhes:
- de prefixo de ID de aplicativo (Team ID)
- ID do pacote
De volta ao Certificados, Identificadores & Perfis, clique em Chaves.
Observação
Se você já tiver uma chave configurada para APNS, poderá reutilizar o certificado p8 baixado logo após sua criação. Em caso afirmativo, pode ignorar os passos 3 a 5.
Clique no botão + (ou no botão Criar uma chave) para criar uma nova chave.
Forneça um valor de de Nome da Chave de
adequado, marque a opção do serviço de Notificações por Push da Apple (APNS) e clique em Continuar , seguido porRegistrar na próxima tela. Clique em
Download e, em seguida, mova o arquivo de p8(prefixado com AuthKey_ ) para um diretório local seguro e, em seguida, clique emConcluído .Observação
Certifique-se de manter seu arquivo p8 em um lugar seguro (e salvar um backup). Depois de baixar sua chave, ela não pode ser baixada novamente, pois a cópia do servidor é removida.
Em Chaves, clique na chave que criou (ou numa chave existente se tiver optado por utilizá-la).
Anote o valor ID da chave de
. Abra seu certificado p8 em um aplicativo adequado de sua escolha, como Visual Studio Code. Anote o valor da chave (entre -----BEGIN PRIVATE KEY----- e -----END PRIVATE KEY-----).
-----COMEÇAR CHAVE PRIVADA-----
<key_value>
-----END CHAVE PRIVADA-----Observação
Este é o de valor de token
que será usado posteriormente para configurar Hub de Notificação .
No final dessas etapas, você deve ter as seguintes informações para uso posterior em Configurar seu hub de notificação com informações do APNS:
- de ID de Equipa (ver passo 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
Regresse ao
Portal de Aprovisionamento do iOS , selecione Certificados, Identificadores & Perfis , selecione Perfis no menu esquerdo e, em seguida, selecione para criar um novo perfil. A tela Registrar um novo perfil de provisionamento é exibida. Selecione iOS App Development em Development como o tipo de perfil de provisionamento e, em seguida, selecione Continue.
Em seguida, selecione o 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
Este certificado não é o certificado push que você criou na etapa anterior . Este é o seu certificado de desenvolvimento. Se não existir, você deve criá-lo, pois este é um pré-requisito para este tutorial. Os certificados de desenvolvedor podem ser criados no Apple Developer Portal, via Xcode ou em Visual Studio.
Regresse à página
Certificados, Identificadores & Perfis, selecione Perfis no menu esquerdo e, em seguida, 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 sua máquina de desenvolvimento.
Criar um Hub de Notificação
Nesta seção, você cria um hub de notificação e configura a autenticação com APNS. Você pode usar um certificado push p12 ou autenticação baseada em token. Se quiser usar um hub de notificação que já criou, pule para a etapa 5.
Entre no Azure.
Clique em Criar um recursoe, em seguida, procure e escolha Hub de Notificaçãoe, em seguida, clique em Criar.
Atualize os seguintes campos e clique em Criar:
DETALHES BÁSICOS
Assinatura: Escolha o dede Assinatura de destino na lista suspensa de Grupo de Recursos
Grupo de Recursos: Criar uma nova(ou escolha uma existente) DETALHES DO NAMESPACE
Namespace do Hub de Notificação: Insira um nome globalmente exclusivo para o namespace do Hub de Notificação doObservação
Verifique se a opção Criar nova
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
Nível de preço: Manter a opção padrão FreeObservação
A menos que você tenha atingido o número máximo de hubs no nível gratuito.
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 de
juntamente com seus valores de Cadeia de Conexão correspondentes.
Configure seu Hub de Notificação com informações do APNS
Em Serviços de Notificação, selecione Apple siga as etapas apropriadas com base na abordagem escolhida anteriormente na seção Criando um certificado para Hubs de Notificação.
Observação
Use o Production for Application Mode somente se quiser enviar notificações por push aos usuários que compraram seu aplicativo na loja.
OPÇÃO 1: Usando um certificado push .p12
Selecione Certificado.
Selecione o ícone do arquivo.
Selecione o ficheiro .p12 que exportou anteriormente e, em seguida, selecione Abrir.
Se necessário, especifique a senha correta.
Selecione modo Sandbox.
Selecione Salvar.
OPÇÃO 2: Usando autenticação baseada em token
Selecione Token.
Insira os seguintes valores adquiridos anteriormente:
- ID da chave
- ID do pacote
- ID da Equipa
- Token
Escolha Sandbox.
Selecione Salvar.
Configure seu hub de notificação com informações do FCM
- Selecione
do Google (GCM/FCM) na seção Configurações do no menu à esquerda. - Introduza a chave do servidor anotou a partir do Google Firebase Console.
- Selecione Salvar na barra de ferramentas.
Criar um aplicativo de back-end da API Web Core do ASP.NET
Nesta seção, você cria o back-end
Criar um projeto Web
No Visual Studio, selecione Arquivo>Nova Solução.
Selecione Aplicativo .NET Core>>ASP.NET API do Core>>Próximo.
Na caixa de diálogo Configurar sua nova ASP.NET Core Web API, selecione do Target Framework de .NET Core 3.1 .
Digite PushDemoApi para a Nome do Projeto e selecione Criar.
Inicie a depuração (Command + Enter) para testar o aplicativo modelado.
Observação
O aplicativo modelo está configurado para usar o WeatherForecastController como o launchUrl. Isso é definido em Propriedades>launchSettings.json.
Se lhe for pedido um certificado de desenvolvimento Inválido encontrado mensagem:
Clique Sim para concordar em executar a ferramenta 'dotnet dev-certs https' para corrigir isso. A ferramenta 'dotnet dev-certs https' solicitará que você insira uma senha para o certificado e a senha para suas chaves.
Clique em Sim quando lhe for pedido para Instalar e confiar no novo certificadoe, em seguida, introduza a palavra-passe para o seu Porta-chaves.
Expanda a pasta controladores
e exclua WeatherForecastController.cs .Excluir WeatherForecast.cs.
Configure valores de configuração local usando a ferramenta Secret Manager. Dissociar os segredos da solução garante que eles não acabem no controle do código-fonte. Abra Terminal 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 pelo seu próprio nome de hub de notificação e valores de cadeia de conexão. Você anotou eles na seção
criar um hub de notificação. Caso contrário, você pode procurá-los no Azure. NotificationHub:Nome:
ConsulteNome no resumo do doEssentials na parte superior Visão geral. NotificationHub:ConnectionString:
Consulte DefaultFullSharedAccessSignature em Políticas de Acesso
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 através do ASP.NET Middleware.
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 valor e anotar isso.
Controle Clique no projetoPushDemoApi, escolha Nova Pasta no menu Adicionar e, em seguida, clique em Adicionar usandode Autenticação como oNome da Pasta . Controle Clique em na pasta Autenticaçãoe, em seguida, escolha Novo Arquivo... no menu Adicionar. Selecione
Classe Geral Vazia , insiraApiKeyAuthOptions.cs para oNome doe clique em Novo adicionar a seguinte implementação.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 outro Empty Class à pasta Authentication chamada ApiKeyAuthHandler.cse, em seguida, adicione a seguinte implementação.
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, neste caso um esquema de chave de API personalizado. Adicione outro de Classe
Vazio à pasta de Autenticação chamada ApiKeyAuthenticationBuilderExtensions.cs e, em seguida, adicione a seguinte implementação.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
Este método de extensão simplifica o código de configuração do middleware em Startup.cs tornando-o mais legível e geralmente mais fácil de seguir.
No Startup.cs, atualize o método ConfigureServices para configurar a autenticação de chave de API abaixo da chamada para os serviços . AddControllers método.
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 no Startup.cs, atualize o método Configure para chamar o UseAuthentication e os métodos de extensão UseAuthorization no IApplicationBuilder do aplicativo. Certifique-se de que esses métodos sejam chamados após UseRouting e antes 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 (do ConfigureServices). Isso deve ser chamado antes de qualquer middleware que dependa da autenticação dos usuários.
Adicionar dependências e configurar serviços
O ASP.NET Core suporta a injeção de dependência de (DI) padrão de design de software, que é uma técnica para alcançar de Inversão de Controle (IoC) 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 é registado e disponibilizado através de uma abstração adequada.
Controle Clique em na pastaDependências e escolha Gerenciar Pacotes NuGet... .Pesquise Microsoft.Azure.NotificationHubs e verifique se ele está verificado.
Clique Adicionar pacotese, em seguida, clique em Aceitar quando solicitado a aceitar os termos de licença.
Controle Clique em no projetoPushDemoApi, escolha Nova Pasta no menu Adicionar e, em seguida, clique em Adicionar usandoModelos como o Nome da Pasta. Controle Clique na pasta Modelose, em seguida, escolha Novo Arquivo... no menu Adicionar. Selecione
Classe Geral Vazia , insiraPushTemplates.cs para aNome dae clique em Novo adicionar a seguinte implementação.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 as cargas úteis de notificação tokenizadas para as notificações genéricas e silenciosas exigidas por esse cenário. As cargas úteis são definidas fora do de Instalação para permitir a experimentação sem ter que atualizar as instalações existentes através do serviço. Lidar com alterações em instalações dessa maneira está fora do escopo deste tutorial. Para produção, considere modelos personalizados.
Adicione outro
Classe Vazia à pasta Modelos chamada DeviceInstallation.cs e, em seguida, adicione a seguinte implementação.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 outro
Classe Vazia à pasta Modelos chamada NotificationRequest.cs e, em seguida, adicione a seguinte implementação.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 outro
Classe Vazia à pasta Models chamada NotificationHubOptions.cs e, em seguida, adicione a seguinte implementação.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 Services.
Adicione um de Interface Vazia de
à pasta Serviços chamada INotificationService.cs e, em seguida, adicione a seguinte implementação.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 um de classe vazia de
à pasta Services chamada NotificationHubsService.cs e, em seguida, adicione o seguinte código para implementar a interfaceINotificationService: 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 tag fornecida ao SendTemplateNotificationAsync é limitada a 20 tags. Limita-se a 6 para a maioria dos operadores, mas a expressão contém apenas RUP (||) neste caso. Se houver mais de 20 tags na solicitação, elas devem ser divididas em várias solicitações. Consulte a documentação Routing and Tag Expressions para obter mais detalhes.
No Startup.cs, atualize o método ConfigureServices para adicionar o NotificationHubsService como uma implementação singleton do 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 em na pastaControllers e, em seguida, escolha Novo Arquivo... no menu Adicionar. Selecione ASP.NET Core>Web API Controller Class, digite NotificationsController para o Nomee, em seguida, clique em Novo.
Observação
Se você estiver seguindo com Visual Studio 2019, escolha o API Controller com ações de leitura/gravação modelo.
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 de modelo para que ele derive de ControllerBase e seja decorado com o atributo ApiController.
[ApiController] [Route("api/[controller]")] public class NotificationsController : ControllerBase { // Templated methods here }
Observação
O Controller classe base fornece suporte para modos de exibição, mas isso não é necessário neste caso e, portanto, ControllerBase pode ser usado em vez disso. Se você estiver seguindo com Visual Studio 2019, poderá ignorar esta etapa.
Se você optar por concluir a seção
Autenticar clientes usando uma chave de API , decore o NotificationsController docom 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 o launchUrl de para api/notifications para corresponder à URL especificada no atributoRegistrationsController Route. Inicie a depuração (
Command Enter ) para validar que o aplicativo está funcionando com o novoNotificationsController e retorna um status de não autorizado 401.Em uma nova guia Postman, defina a solicitação como GET. Digite o endereço abaixo substituindo o espaço reservado
pelo httpsapplicationUrl applicationUrl encontrado em Properties launchSettings.json .<applicationUrl>/api/notifications
Observação
O applicationUrl deve ser 'https://localhost:5001' para o perfil padrão. Se você estiver usando
do IIS (padrão em do Visual Studio 2019 no Windows), use o applicationUrl especificado no itemiisSettings. 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, certifique-se de configurar os cabeçalhos de solicitação para incluir seu valor de apikey.
Chave Valor apikey <your_api_key> Clique no botão Enviar.
Observação
Você deve receber um 200 OK status com algum JSON conteúdo.
Se você receber um aviso de verificação de certificado SSL
, poderá alternar a solicitação de verificação de certificado SSL configuração do Postman noConfigurações do. Substitua os métodos de classe templated no 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 de Aplicativo de API de
Entre no portal do Azure.
Clique em Criar um recursoe, em seguida, procure e escolha API Appe, em seguida, clique em Criar.
Atualize os campos a seguir e clique em Criar.
Nome do aplicativo:
Insira um nome globalmente exclusivo para o API AppSubscrição:
Escolha o mesmo destino Assinatura você criou o hub de notificação.Grupo de Recursos:
Escolha a mesma Grupo de Recursos você criou o hub de notificação.Plano/Localização do Serviço de Aplicativo:
Criar um novo Plano do Serviço de AplicativoObservação
Mude da opção padrão para um plano que inclua suporte a SSL. Caso contrário, você precisará tomar as medidas apropriadas ao trabalhar com o aplicativo móvel para evitar que 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 do aplicativo de API
tiver sido provisionado, navegue até esse recurso. Anote a propriedade URL do
no resumo do do de ponto de extremidade de back-endEssentials na parte superior doVisão geral do . Este URL é o seu 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 de configuração na lista (em Configurações).
Para cada uma das configurações abaixo, clique em
Nova configuração do aplicativo para inserir a Nome doe umaValor e, em seguida, clique em OK .Designação Valor Authentication:ApiKey
<api_key_value> NotificationHub:Name
<hub_name_value> NotificationHub:ConnectionString
<hub_connection_string_value> Observação
Estas 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 é necessária somente se você optar por concluir a seção Autenticar clientes usando uma de chave de API. Para cenários de produção, você pode examinar opções como Azure KeyVault. Estes foram adicionados como configurações de aplicativo para simplicidade neste caso.
Depois que todas as configurações do aplicativo tiverem sido adicionadas, clique Salvare, em seguida, Continuar.
Publicar o serviço de back-end
Em seguida, implante 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 com do 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 Debug para Release se ainda não tiver feito isso.
Controle Clique projeto de PushDemoApi e escolhaPublicar no Azure... no menuPublicar. Siga o fluxo de autenticação se solicitado a fazê-lo. Use a conta que você usou no anterior para criar a seção do aplicativo de API.
Selecione o Aplicativo de API do Serviço de Aplicativo do Azure você criou anteriormente na lista como seu destino de publicação e clique em Publicar.
Depois de concluir o assistente, ele publica o aplicativo no Azure e abre o aplicativo. Anote o URL se ainda não o tiver feito. Este URL é o seu de ponto de extremidade de back-end que é usado posteriormente neste tutorial.
Validando a API publicada
No Postman abrir um novo separador, defina o pedido para PUT e introduza o endereço abaixo. Substitua o espaço reservado pelo endereço base que você anotou na seção anterior publique a seção do 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, certifique-se de configurar os cabeçalhos de solicitação para incluir seu valor de apikey.
Chave Valor apikey <your_api_key> Escolha a opção raw para o Bodye, em seguida, escolha JSON na lista de opções de formato e inclua algum espaço reservado conteúdo JSON:
{}
Clique Enviar.
Observação
Você deve receber um 422 UnprocessableEntity status do serviço.
Execute as etapas 1 a 4 novamente, mas desta vez especificando o ponto de extremidade de solicitações para validar que você recebe uma resposta 400 Bad Request.
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 Xamarin.Forms de plataforma cruzada
Nesta seção, você cria um Xamarin.Forms aplicativo móvel que implementa notificações por push de maneira multiplataforma.
Ele permite que você registre e cancele o registro 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 na central de notificações.
Observação
Normalmente, você executaria as ações de registro (e cancelamento de registro) 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/cancelamento de registro do usuário. No entanto, este exemplo exigirá a entrada explícita do usuário para permitir que essa funcionalidade seja explorada e testada mais facilmente.
Criar a solução Xamarin.Forms
No
Visual Studio , crie uma nova soluçãoXamarin.Forms usando aplicativo Formulários em Branco como modelo e inserindoPushDemo para o Nome do Projeto .Observação
Na caixa de diálogo
Configurar seu aplicativo de formulários em branco , verifique se o do Identificador da Organizaçãocorresponde ao valor usado anteriormente e se os destinos Android e iOS estão marcados.Controle Clique na solução PushDemoe escolha Atualizar Pacotes NuGet .Controle Clique na solução PushDemoe escolha Gerenciar pacotes NuGet. .Procure Newtonsoft.Json e certifique-se de que está verificado.
Clique Adicionar pacotese, em seguida, clique em Aceitar quando solicitado a aceitar os termos de licença.
Crie e execute o aplicativo em cada plataforma de destino (Command + Enter) para testar a execução do aplicativo de modelo no(s) seu(s) dispositivo(s).
Implementar os componentes multiplataforma
Controle Clique em no projetoPushDemo , escolhaNova Pasta no menu Adicionar e, em seguida, clique em Adicionar usandoModelos como o Nome da Pasta. Controle Clique na pasta Modelose, em seguida, escolha Novo Arquivo... no menu Adicionar. Selecione
de Classe Geral Vazia , insira DeviceInstallation.cs e adicione a seguinte implementação.using System.Collections.Generic; using Newtonsoft.Json; namespace PushDemo.Models { public class DeviceInstallation { [JsonProperty("installationId")] public string InstallationId { get; set; } [JsonProperty("platform")] public string Platform { get; set; } [JsonProperty("pushChannel")] public string PushChannel { get; set; } [JsonProperty("tags")] public List<string> Tags { get; set; } = new List<string>(); } }
Adicione um
de enumeração vazia à pasta Models chamada PushDemoAction.cs com a seguinte implementação.namespace PushDemo.Models { public enum PushDemoAction { ActionA, ActionB } }
Adicione uma nova pasta ao projeto
PushDemo chamadoServices adicione uma de classe vazia dea essa pasta chamada ServiceContainer.cs com a seguinte implementação.using System; using System.Collections.Generic; namespace PushDemo.Services { public static class ServiceContainer { static readonly Dictionary<Type, Lazy<object>> services = new Dictionary<Type, Lazy<object>>(); public static void Register<T>(Func<T> function) => services[typeof(T)] = new Lazy<object>(() => function()); public static T Resolve<T>() => (T)Resolve(typeof(T)); public static object Resolve(Type type) { { if (services.TryGetValue(type, out var service)) return service.Value; throw new KeyNotFoundException($"Service not found for type '{type}'"); } } } }
Observação
Esta é uma versão reduzida da classe ServiceContainer do
ServiceContainer do repositório XamCAT . Ele será usado como um recipiente IoC (Inversion of Control) leve. Adicione um
Interface vazia à pasta Serviços chamada IDeviceInstallationService.cs e, em seguida, adicione o código a seguir.using PushDemo.Models; namespace PushDemo.Services { public interface IDeviceInstallationService { string Token { get; set; } bool NotificationsSupported { get; } string GetDeviceId(); DeviceInstallation GetDeviceInstallation(params string[] tags); } }
Observação
Essa interface será implementada e inicializada por cada destino posteriormente para fornecer a funcionalidade específica da plataforma e DeviceInstallation informações exigidas pelo serviço de back-end.
Adicione outro
Interface vazia à pasta Services chamada INotificationRegistrationService.cs e, em seguida, adicione o código a seguir.using System.Threading.Tasks; namespace PushDemo.Services { public interface INotificationRegistrationService { Task DeregisterDeviceAsync(); Task RegisterDeviceAsync(params string[] tags); Task RefreshRegistrationAsync(); } }
Observação
Isso tratará da interação entre o cliente e o serviço de back-end.
Adicione outro
Interface vazia à pasta Services chamada INotificationActionService.cs e, em seguida, adicione o código a seguir.namespace PushDemo.Services { public interface INotificationActionService { void TriggerAction(string action); } }
Observação
Isso é usado como um mecanismo simples para centralizar o processamento de ações de notificação.
Adicione um de Interface Vazia de
à pasta Services chamada IPushDemoNotificationActionService.cs que deriva doINotificationActionService, com a seguinte implementação. using System; using PushDemo.Models; namespace PushDemo.Services { public interface IPushDemoNotificationActionService : INotificationActionService { event EventHandler<PushDemoAction> ActionTriggered; } }
Observação
Esse tipo é específico para o aplicativo PushDemo
e usa a enumeração PushDemoAction para identificar a ação que está sendo acionada de maneira fortemente tipada. Adicione uma de classe vazia
à pasta Services chamada NotificationRegistrationService.cs implementando o INotificationRegistrationServicecom o código a seguir. using System; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; using PushDemo.Models; using Xamarin.Essentials; namespace PushDemo.Services { public class NotificationRegistrationService : INotificationRegistrationService { const string RequestUrl = "api/notifications/installations"; const string CachedDeviceTokenKey = "cached_device_token"; const string CachedTagsKey = "cached_tags"; string _baseApiUrl; HttpClient _client; IDeviceInstallationService _deviceInstallationService; public NotificationRegistrationService(string baseApiUri, string apiKey) { _client = new HttpClient(); _client.DefaultRequestHeaders.Add("Accept", "application/json"); _client.DefaultRequestHeaders.Add("apikey", apiKey); _baseApiUrl = baseApiUri; } IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = ServiceContainer.Resolve<IDeviceInstallationService>()); public async Task DeregisterDeviceAsync() { var cachedToken = await SecureStorage.GetAsync(CachedDeviceTokenKey) .ConfigureAwait(false); if (cachedToken == null) return; var deviceId = DeviceInstallationService?.GetDeviceId(); if (string.IsNullOrWhiteSpace(deviceId)) throw new Exception("Unable to resolve an ID for the device."); await SendAsync(HttpMethod.Delete, $"{RequestUrl}/{deviceId}") .ConfigureAwait(false); SecureStorage.Remove(CachedDeviceTokenKey); SecureStorage.Remove(CachedTagsKey); } public async Task RegisterDeviceAsync(params string[] tags) { var deviceInstallation = DeviceInstallationService?.GetDeviceInstallation(tags); await SendAsync<DeviceInstallation>(HttpMethod.Put, RequestUrl, deviceInstallation) .ConfigureAwait(false); await SecureStorage.SetAsync(CachedDeviceTokenKey, deviceInstallation.PushChannel) .ConfigureAwait(false); await SecureStorage.SetAsync(CachedTagsKey, JsonConvert.SerializeObject(tags)); } public async Task RefreshRegistrationAsync() { var cachedToken = await SecureStorage.GetAsync(CachedDeviceTokenKey) .ConfigureAwait(false); var serializedTags = await SecureStorage.GetAsync(CachedTagsKey) .ConfigureAwait(false); if (string.IsNullOrWhiteSpace(cachedToken) || string.IsNullOrWhiteSpace(serializedTags) || string.IsNullOrWhiteSpace(DeviceInstallationService.Token) || cachedToken == DeviceInstallationService.Token) return; var tags = JsonConvert.DeserializeObject<string[]>(serializedTags); await RegisterDeviceAsync(tags); } async Task SendAsync<T>(HttpMethod requestType, string requestUri, T obj) { string serializedContent = null; await Task.Run(() => serializedContent = JsonConvert.SerializeObject(obj)) .ConfigureAwait(false); await SendAsync(requestType, requestUri, serializedContent); } async Task SendAsync( HttpMethod requestType, string requestUri, string jsonRequest = null) { var request = new HttpRequestMessage(requestType, new Uri($"{_baseApiUrl}{requestUri}")); if (jsonRequest != null) request.Content = new StringContent(jsonRequest, Encoding.UTF8, "application/json"); var response = await _client.SendAsync(request).ConfigureAwait(false); response.EnsureSuccessStatusCode(); } } }
Observação
O argumento apiKey só é necessário se você optar por concluir a seção Autenticar clientes usando uma chave de API.
Adicione uma de classe vazia de
à pasta Services chamada PushDemoNotificationActionService.cs implementar o IPushDemoNotificationActionService docom o código a seguir. using System; using System.Collections.Generic; using System.Linq; using PushDemo.Models; namespace PushDemo.Services { public class PushDemoNotificationActionService : IPushDemoNotificationActionService { readonly Dictionary<string, PushDemoAction> _actionMappings = new Dictionary<string, PushDemoAction> { { "action_a", PushDemoAction.ActionA }, { "action_b", PushDemoAction.ActionB } }; public event EventHandler<PushDemoAction> ActionTriggered = delegate { }; public void TriggerAction(string action) { if (!_actionMappings.TryGetValue(action, out var pushDemoAction)) return; List<Exception> exceptions = new List<Exception>(); foreach (var handler in ActionTriggered?.GetInvocationList()) { try { handler.DynamicInvoke(this, pushDemoAction); } catch (Exception ex) { exceptions.Add(ex); } } if (exceptions.Any()) throw new AggregateException(exceptions); } } }
Adicione um Empty Class ao projeto PushDemo chamado Config.cs com a seguinte implementação.
namespace PushDemo { public static partial class Config { public static string ApiKey = "API_KEY"; public static string BackendServiceEndpoint = "BACKEND_SERVICE_ENDPOINT"; } }
Observação
Isso é usado como uma maneira simples de manter os segredos fora do controle do código-fonte. Você pode substituir esses valores como parte de uma compilação automatizada ou substituí-los usando uma classe parcial local. Você fará isso na próxima etapa.
O campo ApiKey só é obrigatório se você optar por concluir a seção Autenticar clientes usando uma chave de API.
Adicione outro
de classe vazia ao projeto PushDemo desta vez chamado Config.local_secrets.cs com a seguinte implementação.namespace PushDemo { public static partial class Config { static Config() { ApiKey = "<your_api_key>"; BackendServiceEndpoint = "<your_api_app_url>"; } } }
Observação
Substitua os valores de espaço reservado pelos seus. Você deve ter anotado isso quando criou o serviço de back-end. O URL do
API App deve ser . Lembre-se de adicionar *.local_secrets.*
ao seu arquivo gitignore para evitar cometer esse arquivo.O campo ApiKey só é obrigatório se você optar por concluir a seção Autenticar clientes usando uma chave de API.
Adicione uma de classe vazia de
ao projeto de PushDemo chamado Bootstrap.cs com a seguinte implementação.using System; using PushDemo.Services; namespace PushDemo { public static class Bootstrap { public static void Begin(Func<IDeviceInstallationService> deviceInstallationService) { ServiceContainer.Register(deviceInstallationService); ServiceContainer.Register<IPushDemoNotificationActionService>(() => new PushDemoNotificationActionService()); ServiceContainer.Register<INotificationRegistrationService>(() => new NotificationRegistrationService( Config.BackendServiceEndpoint, Config.ApiKey)); } } }
Observação
O método Begin será chamado por cada plataforma quando o aplicativo for iniciado, passando por uma implementação específica da plataforma do IDeviceInstallationService.
O argumento do construtor apiKeyNotificationRegistrationService só é necessário se você optar por concluir a seção Authenticate clients using a API Key seção.
Implementar a interface do usuário entre plataformas
No projeto
PushDemo , abraMainPage.xaml e substitua o controle StackLayout pelo seguinte. <StackLayout VerticalOptions="EndAndExpand" HorizontalOptions="FillAndExpand" Padding="20,40"> <Button x:Name="RegisterButton" Text="Register" Clicked="RegisterButtonClicked" /> <Button x:Name="DeregisterButton" Text="Deregister" Clicked="DeregisterButtonClicked" /> </StackLayout>
Agora no
MainPage.xaml.cs , adicione umcampo de suporte somente leitura para armazenar uma referência à implementaçãoINotificationRegistrationService. readonly INotificationRegistrationService _notificationRegistrationService;
No MainPage construtor, resolva o INotificationRegistrationService implementação usando o ServiceContainer e atribua-o ao notificationRegistrationService campo de suporte.
public MainPage() { InitializeComponent(); _notificationRegistrationService = ServiceContainer.Resolve<INotificationRegistrationService>(); }
Implemente os manipuladores de eventos para os botões RegisterButton e DeregisterButtoneventos Clicked chamando os métodos correspondentes Register/Deregister.
void RegisterButtonClicked(object sender, EventArgs e) => _notificationRegistrationService.RegisterDeviceAsync().ContinueWith((task) => { ShowAlert(task.IsFaulted ? task.Exception.Message : $"Device registered"); }); void DeregisterButtonClicked(object sender, EventArgs e) => _notificationRegistrationService.DeregisterDeviceAsync().ContinueWith((task) => { ShowAlert(task.IsFaulted ? task.Exception.Message : $"Device deregistered"); }); void ShowAlert(string message) => MainThread.BeginInvokeOnMainThread(() => DisplayAlert("PushDemo", message, "OK").ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }));
Agora, em App.xaml.cs, verifique se os namespaces a seguir são referenciados.
using PushDemo.Models; using PushDemo.Services; using Xamarin.Essentials; using Xamarin.Forms;
Implemente o manipulador de eventos para o evento IPushDemoNotificationActionService
ActionTriggered ActionTrigger. void NotificationActionTriggered(object sender, PushDemoAction e) => ShowActionAlert(e); void ShowActionAlert(PushDemoAction action) => MainThread.BeginInvokeOnMainThread(() => MainPage?.DisplayAlert("PushDemo", $"{action} action received", "OK") .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }));
No construtor App, resolva o IPushNotificationActionService implementação usando o ServiceContainer e assine o IPushDemoNotificationActionServiceActionTriggered evento.
public App() { InitializeComponent(); ServiceContainer.Resolve<IPushDemoNotificationActionService>() .ActionTriggered += NotificationActionTriggered; MainPage = new MainPage(); }
Observação
Isso é simplesmente para demonstrar o recebimento e a propagação de ações de notificação por push. Normalmente, eles seriam tratados silenciosamente, por exemplo, navegando para uma exibição específica ou atualizando alguns dados, em vez de exibir um alerta por meio do raizPágina MainPage neste caso.
Configurar o projeto Android nativo para notificações por push
Validar o nome e as permissões do pacote
Em PushDemo.Android , abra o Opções do Projeto e, em seguida, de Aplicativo Android na seção Build.
Verifique se o nome do pacote corresponde ao valor usado no projeto Firebase ConsolePushDemo. O Nome do pacote estava no formato
com.<organization>.pushdemo
.Defina o Versão Mínima do Android para Android 8.0 (nível de API 26) e o Versão Android de Destino para o nível de API mais recente.
Observação
Apenas os dispositivos que executam nível de API 26 e superior são suportados para os fins deste tutorial, no entanto, você pode estendê-lo para suportar dispositivos que executam versões mais antigas.
Verifique se as permissões INTERNET e READ_PHONE_STATE estão habilitadas em Permissões necessárias.
Clique OK
Adicione a base do Xamarin Google Play Services e os pacotes Xamarin.Firebase.Messaging
Em
PushDemo.Android , Controle Clique em na pasta Pacotese escolha Gerenciar pacotes NuGet... .Pesquise Xamarin.GooglePlayServices.Base (não Basement ) e verifique se ele está marcado.
Procure Xamarin.Firebase.Messaging e verifique se ele está verificado.
Clique Adicionar pacotese, em seguida, clique em Aceitar quando solicitado a aceitar os termos de licença .
Adicionar o arquivo JSON dos Serviços Google
Controle Clique em no projetoe, em seguida, escolha Arquivo Existente... no menu Adicionar. Escolha o arquivo google-services.json que você baixou anteriormente ao configurar o projeto PushDemo no Firebase Console clique em Abrir .
Quando solicitado, escolha Copiar o arquivo para o diretório.
Controle + Clique no arquivo de google-services.json de dentro do projeto
PushDemo.Android
e, em seguida, verifique se GoogleServicesJson está definido como o Build Action.
Lidar com notificações push para Android
Controle Clique em no projeto, escolha Nova Pasta no menu Adicionar e, em seguida, clique em Adicionar usandoServices como oNome da Pasta .Controle Clique em na pasta Serviçose, em seguida, escolha Novo Arquivo... no menuAdicionar .Selecione
de Classe Geral Vazia , insira DeviceInstallationService.cs para aNome dae clique em Novo adicionar a seguinte implementação.using System; using Android.App; using Android.Gms.Common; using PushDemo.Models; using PushDemo.Services; using static Android.Provider.Settings; namespace PushDemo.Droid.Services { public class DeviceInstallationService : IDeviceInstallationService { public string Token { get; set; } public bool NotificationsSupported => GoogleApiAvailability.Instance .IsGooglePlayServicesAvailable(Application.Context) == ConnectionResult.Success; public string GetDeviceId() => Secure.GetString(Application.Context.ContentResolver, Secure.AndroidId); public DeviceInstallation GetDeviceInstallation(params string[] tags) { if (!NotificationsSupported) throw new Exception(GetPlayServicesError()); if (string.IsNullOrWhiteSpace(Token)) throw new Exception("Unable to resolve token for FCM"); var installation = new DeviceInstallation { InstallationId = GetDeviceId(), Platform = "fcm", PushChannel = Token }; installation.Tags.AddRange(tags); return installation; } string GetPlayServicesError() { int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(Application.Context); if (resultCode != ConnectionResult.Success) return GoogleApiAvailability.Instance.IsUserResolvableError(resultCode) ? GoogleApiAvailability.Instance.GetErrorString(resultCode) : "This device is not supported"; return "An error occurred preventing the use of push notifications"; } } }
Observação
Essa classe fornece uma ID exclusiva (usando Secure.AndroidId) como parte da carga útil de registro do hub de notificação.
Adicione outro
Empty Class à pastaServices chamada PushNotificationFirebaseMessagingService.cs e, em seguida, adicione a seguinte implementação.using Android.App; using Android.Content; using Firebase.Messaging; using PushDemo.Services; namespace PushDemo.Droid.Services { [Service] [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })] public class PushNotificationFirebaseMessagingService : FirebaseMessagingService { IPushDemoNotificationActionService _notificationActionService; INotificationRegistrationService _notificationRegistrationService; IDeviceInstallationService _deviceInstallationService; IPushDemoNotificationActionService NotificationActionService => _notificationActionService ?? (_notificationActionService = ServiceContainer.Resolve<IPushDemoNotificationActionService>()); INotificationRegistrationService NotificationRegistrationService => _notificationRegistrationService ?? (_notificationRegistrationService = ServiceContainer.Resolve<INotificationRegistrationService>()); IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = ServiceContainer.Resolve<IDeviceInstallationService>()); public override void OnNewToken(string token) { DeviceInstallationService.Token = token; NotificationRegistrationService.RefreshRegistrationAsync() .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }); } public override void OnMessageReceived(RemoteMessage message) { if(message.Data.TryGetValue("action", out var messageAction)) NotificationActionService.TriggerAction(messageAction); } } }
No MainActivity.cs, verifique se os namespaces a seguir foram adicionados à parte superior do arquivo.
using System; using Android.App; using Android.Content; using Android.Content.PM; using Android.OS; using Android.Runtime; using Firebase.Iid; using PushDemo.Droid.Services; using PushDemo.Services;
No
MainActivity.cs , defina o LaunchModecomo SingleTop para que MainActivity não seja criado novamente quando aberto. [Activity( Label = "PushDemo", LaunchMode = LaunchMode.SingleTop, Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
Adicione propriedades privadas e campos de suporte correspondentes para armazenar uma referência às implementações
IPushNotificationActionService eIDeviceInstallationService. IPushDemoNotificationActionService _notificationActionService; IDeviceInstallationService _deviceInstallationService; IPushDemoNotificationActionService NotificationActionService => _notificationActionService ?? (_notificationActionService = ServiceContainer.Resolve<IPushDemoNotificationActionService>()); IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = ServiceContainer.Resolve<IDeviceInstallationService>());
Implemente o
interface IOnSuccessListener para recuperar e armazenar o tokenFirebase. public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, Android.Gms.Tasks.IOnSuccessListener { ... public void OnSuccess(Java.Lang.Object result) => DeviceInstallationService.Token = result.Class.GetMethod("getToken").Invoke(result).ToString(); }
Adicione um novo método chamado ProcessNotificationActions que verificará se um determinado de intenção tem um valor extra chamado ação. Acione condicionalmente essa ação usando o IPushDemoNotificationActionService implementação.
void ProcessNotificationActions(Intent intent) { try { if (intent?.HasExtra("action") == true) { var action = intent.GetStringExtra("action"); if (!string.IsNullOrEmpty(action)) NotificationActionService.TriggerAction(action); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } }
Substitua o método OnNewIntent para chamar método ProcessNotificationActions.
protected override void OnNewIntent(Intent intent) { base.OnNewIntent(intent); ProcessNotificationActions(intent); }
Observação
Como o LaunchMode do
para o de Atividade está definido como SingleTop , um de Intenção de será enviado para a instância de de Atividade do existente por meio do método OnNewIntent em vez do método OnCreate e, portanto, você deve manipular uma intenção de entrada nos métodos OnCreate eOnNewIntent. Atualize o método
OnCreate para chamar logo após a chamada para passando a implementação específica da plataforma do IDeviceInstallationService .Bootstrap.Begin(() => new DeviceInstallationService());
No mesmo método, chame condicionalmente
GetInstanceId na instância FirebaseApp, logo após a chamada para , adicionando MainActivity como o IOnSuccessListener .if (DeviceInstallationService.NotificationsSupported) { FirebaseInstanceId.GetInstance(Firebase.FirebaseApp.Instance) .GetInstanceId() .AddOnSuccessListener(this); }
Ainda no
OnCreate , chameProcessNotificationActions imediatamente após a chamada parapassando node intenção de atual. ... LoadApplication(new App()); ProcessNotificationActions(Intent);
Observação
Você deve registrar novamente o aplicativo sempre que executá-lo e interrompê-lo de uma sessão de depuração para continuar recebendo notificações por push.
Configurar o projeto iOS nativo para notificações por push
Configurar Info.plist e Entitlements.plist
Certifique-se de que iniciou sessão na sua conta de programador Apple
em Visual Studio Preferências... Publicação Contas de Programador Apple e a de Certificados deapropriada e de Perfil de Aprovisionamento de foram transferidas. Você deve ter criado esses ativos como parte das etapas anteriores. Em PushDemo.iOS , abra Info.plist e verifique se o BundleIdentifier corresponde ao valor que foi usado para o respetivo perfil de provisionamento no Apple Developer Portal. O BundleIdentifier estava no formato
com.<organization>.PushDemo
.No mesmo ficheiro, defina Versão mínima do sistema para 13.0.
Observação
Apenas os dispositivos que executam iOS 13.0 e superior são suportados para os fins deste tutorial, no entanto, você pode estendê-lo para suportar dispositivos que executam versões mais antigas.
Abra o
Opções do Projeto para PushDemo.iOS (clique duas vezes no projeto). Em Opções do Projeto , em de Assinatura do Pacote iOS Criar > , verifique se sua conta de Desenvolvedor está selecionada em Team. Em seguida, verifique se a opção "Gerenciar assinatura automaticamente" está selecionada e se o Certificado de Assinatura e o Perfil de Provisionamento são selecionados automaticamente.
Observação
Se o seu de Certificado de Assinatura de
e de Perfil de Provisionamento de de Equipanão tiverem sido selecionados automaticamente, escolha de Provisionamento Manual e clique em Opções de Assinatura de Pacote . Certifique-se de que o seuestá selecionado para de Identidade de Assinatura e que o seu perfil de provisionamento específico do PushDemo está selecionado parade Perfil de Aprovisionamento para configurações de de Depuração e de Lançamento, garantindo que iPhone esteja selecionado para o da Plataforma em ambos os casos. Em
PushDemo.iOS , abra Entitlements.plist e verifique se Ativar notificações por push está marcada quando visualizada na guia Direitos . Em seguida, verifique se a configuração APS Environment está definida parade desenvolvimento quando visualizada na guia de origem.
Lidar com notificações por push para iOS
Controle Clique em no projetoPushDemo.iOS, escolha Nova Pasta no menu Adicionar e, em seguida, clique em Adicionar usandoServices como oNome da Pasta .Controle Clique em na pasta Serviçose, em seguida, escolha Novo Arquivo... no menuAdicionar .Selecione
de Classe Geral Vazia , insira DeviceInstallationService.cs para aNome dae clique em Novo adicionar a seguinte implementação.using System; using PushDemo.Models; using PushDemo.Services; using UIKit; namespace PushDemo.iOS.Services { public class DeviceInstallationService : IDeviceInstallationService { const int SupportedVersionMajor = 13; const int SupportedVersionMinor = 0; public string Token { get; set; } public bool NotificationsSupported => UIDevice.CurrentDevice.CheckSystemVersion(SupportedVersionMajor, SupportedVersionMinor); public string GetDeviceId() => UIDevice.CurrentDevice.IdentifierForVendor.ToString(); public DeviceInstallation GetDeviceInstallation(params string[] tags) { if (!NotificationsSupported) throw new Exception(GetNotificationsSupportError()); if (string.IsNullOrWhiteSpace(Token)) throw new Exception("Unable to resolve token for APNS"); var installation = new DeviceInstallation { InstallationId = GetDeviceId(), Platform = "apns", PushChannel = Token }; installation.Tags.AddRange(tags); return installation; } string GetNotificationsSupportError() { if (!NotificationsSupported) return $"This app only supports notifications on iOS {SupportedVersionMajor}.{SupportedVersionMinor} and above. You are running {UIDevice.CurrentDevice.SystemVersion}."; if (Token == null) return $"This app can support notifications but you must enable this in your settings."; return "An error occurred preventing the use of push notifications"; } } }
Observação
Essa classe fornece uma ID exclusiva (usando o valor UIDevice.IdentifierForVendor) e a carga útil de registro do hub de notificação.
Adicione uma nova pasta ao projeto PushDemo.iOS
chamado Extensions adicione umEmpty Class a essa pasta chamadaNSDataExtensions.cs com a seguinte implementação.using System.Text; using Foundation; namespace PushDemo.iOS.Extensions { internal static class NSDataExtensions { internal static string ToHexString(this NSData data) { var bytes = data.ToArray(); if (bytes == null) return null; StringBuilder sb = new StringBuilder(bytes.Length * 2); foreach (byte b in bytes) sb.AppendFormat("{0:x2}", b); return sb.ToString().ToUpperInvariant(); } } }
No AppDelegate.cs, verifique se os namespaces a seguir foram adicionados à parte superior do arquivo.
using System; using System.Diagnostics; using System.Threading.Tasks; using Foundation; using PushDemo.iOS.Extensions; using PushDemo.iOS.Services; using PushDemo.Services; using UIKit; using UserNotifications; using Xamarin.Essentials;
Adicione propriedades privadas e seus respetivos campos de suporte para armazenar uma referência às implementações de IPushDemoNotificationActionService
IPushDemoNotificationService, INotificationRegistrationService e IDeviceInstallationService. IPushDemoNotificationActionService _notificationActionService; INotificationRegistrationService _notificationRegistrationService; IDeviceInstallationService _deviceInstallationService; IPushDemoNotificationActionService NotificationActionService => _notificationActionService ?? (_notificationActionService = ServiceContainer.Resolve<IPushDemoNotificationActionService>()); INotificationRegistrationService NotificationRegistrationService => _notificationRegistrationService ?? (_notificationRegistrationService = ServiceContainer.Resolve<INotificationRegistrationService>()); IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = ServiceContainer.Resolve<IDeviceInstallationService>());
Adicione o método
RegisterForRemoteNotifications para registrar as configurações de notificação do usuário e, em seguida, para notificações remotas com APNS .void RegisterForRemoteNotifications() { MainThread.BeginInvokeOnMainThread(() => { var pushSettings = UIUserNotificationSettings.GetSettingsForTypes( UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, new NSSet()); UIApplication.SharedApplication.RegisterUserNotificationSettings(pushSettings); UIApplication.SharedApplication.RegisterForRemoteNotifications(); }); }
Adicione o método CompleteRegistrationAsync para definir o valor da propriedade
IDeviceInstallationService.Token
. Atualize o registro e armazene em cache o token do dispositivo se ele tiver sido atualizado desde a última vez que foi armazenado.Task CompleteRegistrationAsync(NSData deviceToken) { DeviceInstallationService.Token = deviceToken.ToHexString(); return NotificationRegistrationService.RefreshRegistrationAsync(); }
Adicione o método
ProcessNotificationActions para processar os dados de notificação deNSDictionary e chamar condicionalmente NotificationActionService.TriggerAction .void ProcessNotificationActions(NSDictionary userInfo) { if (userInfo == null) return; try { var actionValue = userInfo.ObjectForKey(new NSString("action")) as NSString; if (!string.IsNullOrWhiteSpace(actionValue?.Description)) NotificationActionService.TriggerAction(actionValue.Description); } catch (Exception ex) { Debug.WriteLine(ex.Message); } }
Substitua o método
RegisteredForRemoteNotifications passando o argumento deviceToken para ométodo CompleteRegistrationAsync.public override void RegisteredForRemoteNotifications( UIApplication application, NSData deviceToken) => CompleteRegistrationAsync(deviceToken).ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; });
Substitua o método
ReceivedRemoteNotification passando o argumento userInfo para ométodo ProcessNotificationActions.public override void ReceivedRemoteNotification( UIApplication application, NSDictionary userInfo) => ProcessNotificationActions(userInfo);
Substitua o método
FailedToRegisterForRemoteNotifications para registrar o erro. public override void FailedToRegisterForRemoteNotifications( UIApplication application, NSError error) => Debug.WriteLine(error.Description);
Observação
Trata-se, em grande medida, de um espaço reservado. Você desejará implementar o registro em log e o tratamento de erros adequados para cenários de produção.
Atualize o método
FinishedLaunching para chamar logo após a chamada para passando na implementação específica da plataforma doIDeviceInstallationService . Bootstrap.Begin(() => new DeviceInstallationService());
No mesmo método, solicite condicionalmente a autorização e registre-se para notificações remotas imediatamente após
Bootstrap.Begin
.if (DeviceInstallationService.NotificationsSupported) { UNUserNotificationCenter.Current.RequestAuthorization( UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound, (approvalGranted, error) => { if (approvalGranted && error == null) RegisterForRemoteNotifications(); }); }
Ainda em FinishedLaunch , chame ProcessNotificationActions imediatamente após a chamada para
LoadApplication
se as opções de argumento contiver o UIApplication.LaunchOptionsRemoteNotificationKey passando o objeto resultante userInfo.using (var userInfo = options?.ObjectForKey( UIApplication.LaunchOptionsRemoteNotificationKey) as NSDictionary) ProcessNotificationActions(userInfo);
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 um novo separador no Postman.
Defina a solicitação como POSTe digite 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, certifique-se de configurar os cabeçalhos de solicitação para incluir seu valor de apikey.
Chave Valor apikey <your_api_key> Escolha a opção raw para o Bodye, em seguida, escolha JSON na lista de opções de formato e inclua algum espaço reservado conteúdo JSON:
{ "text": "Message from Postman!", "action": "action_a" }
Selecione o botão Code, que está sob o 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 em Android certifique-se de que não está executando em de depuração , ou se o aplicativo foi implantado executando o aplicativo, force o fechamento do aplicativo e inicie-o novamente a partir do iniciador.
No aplicativo PushDemo, toque no botão Registrar.
De volta ao
, feche a janelaPostman Gerar trechos de código (se ainda não tiver feito isso) e clique no botão Enviar .Valide que você recebe uma resposta
200 OK noPostman e o alerta aparece no aplicativo mostrando ação ActionA recebida .Feche o aplicativo PushDemo
e clique no botão Enviar novamente noPostman. Valide que você recebe uma resposta 200 OK em 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 ela abre o aplicativo e exibiu o ação ActionA recebeu alerta.
De volta ao Postman, modifique o corpo da solicitação anterior para enviar uma notificação silenciosa especificando action_b em vez de action_a para a ação valor.
{ "action": "action_b", "silent": true }
Com o aplicativo ainda aberto, clique no botão Enviar no Postman.
Valide se você recebe uma resposta 200 OK no Postman e que o alerta aparece no aplicativo mostrando ação ActionB recebida em vez de ação ActionA recebida.
Feche o aplicativo PushDemo
e clique no botão Enviar novamente noPostman. Valide se você recebe uma resposta
200 OK noPostman e que 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 usando a porta correta.
Se o teste em relação ao Aplicativo de API do Azure, verifique se o serviço está em execução, foi implantado e iniciado sem erros.
Certifique-se de verificar se você especificou o endereço base corretamente em Postman ou na configuração do aplicativo móvel ao testar através do cliente. O endereço base deve ser https://<api_name>.azurewebsites.net/
ou https://localhost:5001/
ao testar localmente.
Não receber notificações no Android depois de iniciar ou parar uma sessão de depuração
Certifique-se de se registrar novamente depois de iniciar ou parar 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 de status 401 do serviço de back-end
Valide se você está definindo o cabeçalho de solicitação de apikey
Se você receber esse erro ao testar localmente, verifique se o valor da chave definida na configuração do cliente corresponde ao valor de configuração do usuário Authentication:ApiKey usado pela API .
Se você estiver testando com um 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ê optou por não concluir a seção
Recebendo um código de status 404 do serviço de back-end
Valide se o método de ponto de extremidade e solicitação HTTP está correto. Por exemplo, os parâmetros de avaliação devem ser, a título indicativo:
-
[PUT]
https://<api_name>.azurewebsites.net/api/notifications/installations
-
[EXCLUIR]
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
-
[EXCLUIR]
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/
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 o código de status da resposta Http definindo um ponto de interrupção para inspecionar o StatusCode valor da propriedade no HttpResponse.
Analise as sugestões de solução de problemas anteriores, quando aplicável, com base no código de status.
Defina um ponto de interrupção nas linhas que retornam esses códigos de status específicos para a respetiva 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 a carga útil apropriada. Use a carga real criada pelo código do cliente para a plataforma em questão.
Revise 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
e token
variáveis para a plataforma apropriada.
Não é possível resolver um ID para a mensagem de erro do dispositivo é exibida
Revise as seções de configuração específicas da plataforma para garantir que nenhuma etapa tenha sido perdida.
Ligações úteis
- Visão geral dos Hubs de Notificação do Azure
- Instalando o Visual Studio para Mac
- Instalando o Xamarin no Windows
- SDK dos Hubs de Notificação para operações de back-end
- SDK dos Hubs de Notificação no GitHub
- Registre-se com o de back-end do aplicativo
- Gestão de registos
- Trabalhando com tags
- Trabalhando com modelos personalizados
Próximos passos
Agora você deve ter um aplicativo Xamarin.Forms 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.
Você provavelmente precisará adaptar o exemplo usado neste tutorial para se adequar ao seu próprio cenário. A implementação de tratamento de erros mais robusto, lógica de repetição e registro em log também é recomendada.
do Visual Studio App Center podem ser rapidamente incorporados a aplicativos móveis fornecendo de análise e diagnósticos para ajudar na solução de problemas.