Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Explorar o de exemplo
As notificações por push fornecem informações de um sistema de back-end para um aplicativo cliente. Apple, Google e outras plataformas têm seu próprio Serviço de Notificação por Push (PNS). Os Hubs de Notificação do Azure permitem centralizar notificações entre plataformas para que seu aplicativo de back-end possa se comunicar com um único hub, que se encarrega de distribuir notificações para cada PNS.
Os Hubs de Notificação do Azure exigem que os aplicativos se registrem no hub e, opcionalmente, definam modelos e/ou assinem tags:
- Executar a configuração de um dispositivo vincula um identificador do serviço de notificações push (PNS) a um identificador no Hub de Notificação do Azure. Para obter mais informações sobre registros, consulte Gerenciamento de registros.
- Os modelos permitem que os dispositivos especifiquem modelos de mensagens parametrizadas. As mensagens recebidas podem ser personalizadas por dispositivo. Para obter mais informações, consulte Modelos de hubs de notificação.
- As tags podem ser usadas para se inscrever em categorias de mensagens, como notícias, esportes e meteorologia. Para obter mais informações, consulte Roteamento e expressões de tag.
Neste tutorial, você usará Hubs de Notificação do Azure para enviar notificações por push para um aplicativo .NET Multi-platform App UI (.NET MAUI) 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 e para iniciar uma notificação por push. Essas operações são tratadas usando o pacote Microsoft.Azure.NotificationHubs NuGet. Para obter mais informações sobre a abordagem geral, consulte Gestão de registos do servidor back-end.
Neste tutorial, você:
- Configure os serviços de notificação por push e o Hub de Notificação do Azure.
- Crie um aplicativo de back-end ASP.NET Core WebAPI.
- Crie um aplicativo .NET MAUI.
- Configure o aplicativo Android para notificações por push.
- Configure o aplicativo iOS para notificações por push.
- Teste o aplicativo.
- Solucione quaisquer problemas de instalação e configuração.
Pré-requisitos
Para concluir este tutorial, você precisará:
- Uma conta Azure com uma subscrição ativa.
- Um PC ou Mac executando a versão mais recente do Visual Studio/Visual Studio Code com a carga de trabalho de desenvolvimento da interface do usuário do aplicativo multiplataforma .NET e as cargas de trabalho de desenvolvimento ASP.NET e da Web instaladas.
Para Android, você deve ter:
- Um dispositivo físico desbloqueado pelo desenvolvedor, ou um emulador, executando a API 26+ com o Google Play Services instalado.
Para iOS, você deve ter:
- Uma conta de programador Apple ativa.
- Um Mac com Xcode, juntamente com um certificado de programador válido instalado no seu Porta-chaves.
Em seguida, no iOS deverás ter:
Um simulador iOS 16+ que roda no macOS 13+ em computadores Mac com processadores de silício ou T2 da Apple.
OU
Um dispositivo iOS físico registado na sua conta de programador (com iOS 13.0+).
O seu dispositivo físico registado na sua conta de programador Apple e associado ao seu certificado.
Importante
O simulador iOS suporta notificações remotas no iOS 16+ quando executado no macOS 13+ em computadores Mac com processadores de silício ou T2 da Apple. Se não cumprir estes requisitos de hardware, necessitará de uma conta de programador Apple ativa e de um dispositivo físico.
Para seguir este tutorial, você deve estar familiarizado com:
- Portal do Desenvolvedor da Apple
- ASP.NET Core e APIs da Web
- Firebase Cloud Messaging
- Microsoft Azure
Embora este tutorial tenha como alvo o Visual Studio, é possível segui-lo usando o Visual Studio Code em um PC ou Mac. No entanto, haverá algumas diferenças que precisam de ser conciliadas. Por exemplo, descrições da interface do usuário e fluxos de trabalho, nomes de modelo e configuração de ambiente.
Configurar serviços de notificação por push e o Hub de Notificação do Azure
Nesta seção, você configurará Firebase Cloud Messaging e Apple Push Notification Services (APNS). Em seguida, você criará e configurará um do Hub de Notificação do Azure para trabalhar com esses serviços.
Criar um projeto do Firebase
Para criar um projeto do Firebase:
Num navegador web, inicie sessão no console do Firebase.
No console do Firebase, selecione o botão Adicionar projeto e 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 inclui 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 suas edições ainda sejam globalmente exclusivas.
Depois que seu projeto for criado, selecione o logotipo do Android para adicionar o Firebase a um aplicativo Android:
Na página Adicionar Firebase à sua aplicação Android, introduza um nome para o seu pacote, opcionalmente uma alcunha de aplicação, e selecione o botão Registar aplicação:
Na página Adicionar Firebase ao seu aplicativo Android, selecione o botão Download google-services.json e salve o arquivo em uma pasta local antes de selecionar o botão Avançar:
Na página Adicionar Firebase ao seu aplicativo Android, selecione o botão Avançar.
Na página Adicionar o Firebase à sua aplicação Android, selecione o botão Continuar para o console.
No console do Firebase, selecione o ícone Visão geral do projeto e, em seguida, selecione Configurações do projeto:
Nas Configurações do projeto, selecione a aba Cloud Messaging. Vai ver que a API do Firebase Cloud Messaging (V1) está ativada:
Nas Configurações do projeto , selecione a guia Contas de serviço e, em seguida, selecione o botão Gerar nova chave privada .
Na caixa de diálogo Gerar nova chave privada, selecione o botão Gerar chave:
Será baixado um arquivo JSON, que conterá os valores que você inserirá no Hub de Notificação do Azure.
Registre seu aplicativo iOS para notificações por push
Para enviar notificações push para uma aplicação iOS, terá de registar a sua aplicação na Apple e registar-se para receber notificações push. Isso pode ser feito executando as etapas na seguinte documentação do Hub de Notificação do Azure:
- Gerar o arquivo de solicitação de assinatura de certificado
- Registre seu aplicativo para receber notificações por push
- Criar um certificado para o hub de notificação
Se quiser receber notificações por push em um dispositivo físico, você também precisará criar um perfil de provisionamento.
Importante
Para receber notificações em segundo plano no iOS, você deve adicionar o modo de plano de fundo de notificações remotas ao seu aplicativo. Para obter mais informações, consulte Habilitar o recurso de notificações remotas no developer.apple.com.
Criar um Hub de Notificação do Azure
Para criar um hub de notificação no portal do Azure:
- Em um navegador Web, inicie sessão no portal do Azure.
- No portal do Azure, clique no botão Criar um recurso e, em seguida, procure e escolha Hub de Notificação antes de selecionar o botão Criar.
- Na página do Hub de Notificação, execute as seguintes etapas:
No campo Subscrição, selecione o nome da subscrição do Azure que pretende utilizar e, em seguida, selecione um grupo de recursos existente ou crie um novo.
No campo Detalhes do Namespace, insira um nome único para o novo namespace.
No campo Detalhes do Hub de Notificação, digite um nome para o hub de notificação. Isso é necessário porque um namespace contém um ou mais hubs de notificação.
Na lista suspensa Local, escolha um valor que especifique o local onde pretende criar o hub de notificações.
Revise a opção de Zonas de Disponibilidade . Se você escolher uma região com zonas de disponibilidade, a caixa de seleção será selecionada por padrão.
Observação
As zonas de disponibilidade são um recurso pago, portanto, uma taxa adicional é adicionada ao seu nível.
Escolha uma opção recuperação de desastres: nenhuma, região de recuperação emparelhada ou região de recuperação flexível. Se você escolher região de recuperação emparelhada, a região de failover será exibida. Se selecionares Região de recuperação flexível, utiliza o menu suspenso para escolher uma das regiões de recuperação.
Selecione o botão Criar. O hub de notificação será criado.
- No portal do Azure, navegue até o seu hub de notificação recém-criado e, em seguida, até a folha Gerenciar > Políticas de Acesso.
- Na folha Políticas de Acesso, anote a cadeia de conexão da política de
DefaultFullSharedAccessSignature
. Você precisará disso mais tarde ao criar um serviço de back-end que se comunique com seu hub de notificação.
Para obter mais informações sobre como criar um hub de notificação, consulte Criar um hub de notificação do Azure no portal do Azure.
Configurar o Firebase Cloud Messaging no hub de notificação
Para configurar seu hub de notificação para se comunicar com o Firebase Cloud Messaging:
Na do portal doAzure , navegue até o hub de notificação e selecione a folha Configurações > Google (FCM v1).
Na folha Google (FCM v1) , insira valores para os campos de Chave Privada , e-mail do cliente e ID do projeto . Esses valores podem ser encontrados no arquivo JSON de chave privada que você baixou do Firebase Cloud Messaging:
Campo Azure Chave JSON Exemplo de valor JSON Chave Privada private_key
Esse valor deve começar com -----BEGIN PRIVATE KEY-----\n
e terminar com-----END PRIVATE KEY-----\n
.E-mail do cliente client_email
firebase-adminsdk-55sfg@pushdemo-d6ab2.iam.gserviceaccount.com
ID do projeto project_id
pushdemo-d6ab2
Na folha Google (FCM v1), selecione o botão Salvar.
Configurar o Serviço de Notificação por Push da Apple no hub de notificação
No portal do Azure, navegue até o hub de notificação e selecione a folha Configurações > Apple (APNS). Em seguida, siga as etapas apropriadas com base na abordagem escolhida anteriormente ao criar um certificado para o hub de notificação.
Importante
Ao definir o Modo de Aplicativo, escolha apenas Produção se quiser enviar notificações por push aos utilizadores que compraram o seu aplicativo na loja.
Opção 1 - Usar um certificado push .p12
- Na lâmina Apple (APNS), selecione a autenticação pelo modo de Certificado.
- Na seção Apple (APNS), selecione o ícone de ficheiro ao lado do campo Upload Certificate. Em seguida, selecione o arquivo .p12 que você exportou anteriormente e carregue-o.
- Na folha Apple (APNS), insira a senha do certificado no campo Senha, se necessário.
- Na folha Apple (APNS), selecione o Sandbox modo de aplicação.
- Na folha Apple (APNS), selecione o botão Salvar.
Opção 2 - Usar autenticação baseada em token
- Na folha Apple (APNS), selecione o modo de autenticação Token .
- Na folha Apple (APNS), insira os valores adquiridos anteriormente para os campos Key Id, Bundle Id, Team Ide Token.
- Na folha Apple (APNS), selecione o modo de aplicação Sandbox.
- Na folha Apple (APNS), selecione o botão Salvar.
Criar uma aplicação de back-end ASP.NET Core Web API
Nesta secção, criará um back-end da API Web ASP.NET Core para lidar com a instalação de dispositivos e enviar notificações para a aplicação .NET MAUI.
Criar um projeto de API da Web
Para criar um projeto de API da Web:
No Visual Studio, crie uma API Web ASP.NET Core projeto:
Na caixa de diálogo Configurar o seu novo projeto, dê o nome ao projeto PushNotificationsAPI.
Na caixa de diálogo Informações adicionais, verifique se as caixas de seleção Configurar para HTTPS e Usar controladores estão habilitadas.
Depois que o projeto tiver sido criado, pressione F5 para executar o projeto.
No momento, o aplicativo está configurado para usar o
WeatherForecastController
como olaunchUrl
, que é definido no\launchSettings.jsPropriedades em arquivo. O aplicativo será iniciado em um navegador da Web e exibirá alguns dados JSON.Importante
Quando você executa um projeto ASP.NET Core que usa HTTPS, o Visual Studio detetará se o certificado de desenvolvimento ASP.NET Core HTTPS está instalado em seu armazenamento de certificados de usuário local e oferecerá para instalá-lo e confiar nele se estiver faltando.
Feche o navegador da Web.
No Explorador de Soluções, expanda a pasta Controladores e exclua WeatherForecastController.cs.
No Gerenciador de Soluções , na raiz do projeto, exclua WeatherForecast.cs.
Abra uma janela de comando e navegue até o diretório que contém o arquivo de projeto. Em seguida, 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 placeholders pelos seus próprios nome do Hub de Notificação do Azure e os valores da string de conexão. Eles podem ser encontrados nos seguintes locais em seu Hub de Notificação do Azure:
Valor de configuração Localização NotificationHub:Name
Consulte Nome no resumo do do Essentials na parte superior da página Visão Geral do. NotificationHub:ConnectionString
Consulte DefaultFullSharedAccessSignature* na página Políticas de Acesso. Isso define valores de configuração local usando a ferramenta Secret Manager. Isso separa seus segredos do Hub de Notificação do Azure da solução Visual Studio, para garantir que eles não acabem no controle do código-fonte.
Autenticar clientes com uma chave de API
Para autenticar clientes com uma chave de API:
Abra uma janela de comando e navegue até o diretório que contém o arquivo de projeto. Em seguida, execute os seguintes comandos:
dotnet user-secrets set "Authentication:ApiKey" <value>
Substitua o valor do espaço reservado pela sua chave da API, sendo que esta pode ser qualquer valor.
No Visual Studio, adicione uma nova pasta chamada Authentication ao seu projeto e, em seguida, adicione uma nova classe chamada
ApiKeyAuthOptions
à pasta Authentication e substitua seu código pelo seguinte código:using Microsoft.AspNetCore.Authentication; namespace PushNotificationsAPI.Authentication; public class ApiKeyAuthOptions : AuthenticationSchemeOptions { public const string DefaultScheme = "ApiKey"; public string Scheme => DefaultScheme; public string ApiKey { get; set; } }
No Visual Studio, adicione uma nova classe chamada
ApiKeyAuthHandler
à pasta Authentication e substitua seu código pelo seguinte código:using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.Options; using System.Security.Claims; using System.Text.Encodings.Web; namespace PushNotificationsAPI.Authentication; public class ApiKeyAuthHandler : AuthenticationHandler<ApiKeyAuthOptions> { const string ApiKeyIdentifier = "apikey"; public ApiKeyAuthHandler( IOptionsMonitor<ApiKeyAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder) { } 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)); } }
Um manipulador de autenticação é um tipo que implementa o comportamento de um esquema, que neste caso é um esquema de chave de API personalizado.
No Visual Studio, adicione uma nova classe chamada
AuthenticationBuilderExtensions
à pasta Authentication e substitua seu código pelo seguinte código:using Microsoft.AspNetCore.Authentication; namespace PushNotificationsAPI.Authentication; public static class AuthenticationBuilderExtensions { public static AuthenticationBuilder AddApiKeyAuth( this AuthenticationBuilder builder, Action<ApiKeyAuthOptions> configureOptions) { return builder .AddScheme<ApiKeyAuthOptions, ApiKeyAuthHandler>( ApiKeyAuthOptions.DefaultScheme, configureOptions); } }
Este método de extensão será usado para simplificar o código de configuração do middleware em Program.cs.
No Visual Studio, abra o Program.cs e atualize o código para configurar a autenticação de chave de API abaixo da chamada para o método
builder.Services.AddControllers
:using PushNotificationsAPI.Authentication; builder.Services.AddControllers(); builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = ApiKeyAuthOptions.DefaultScheme; options.DefaultChallengeScheme = ApiKeyAuthOptions.DefaultScheme; }).AddApiKeyAuth(builder.Configuration.GetSection("Authentication").Bind);
No Program.cs, atualize o código abaixo do comentário
// Configure the HTTP request pipeline
para chamar os métodos de extensãoUseRouting
,UseAuthentication
eMapControllers
:// Configure the HTTP request pipeline. app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
O método de extensão
UseAuthentication
registra o middleware que usa o esquema de autenticação registrado anteriormente.UseAuthentication
deve ser chamado antes de qualquer middleware que dependa da autenticação dos usuários.Observação
Embora uma chave de API não seja tão segura quanto um token, ela será suficiente para este tutorial e será facilmente configurada por meio do ASP.NET Middleware.
Adicionar e configurar serviços
Para adicionar e configurar serviços em seu aplicativo de back-end da API Web:
No Visual Studio, adicione o Microsoft.Azure.NotificationHubs pacote NuGet ao seu projeto. Este pacote NuGet é usado para acessar seu hub de notificação, encapsulado em um serviço.
No Visual Studio, adicione uma nova pasta chamada Models ao seu projeto e, em seguida, adicione uma nova classe chamada
PushTemplates
à pasta Models e substitua seu código pelo seguinte código:namespace PushNotificationsAPI.Models; public class PushTemplates { public class Generic { public const string Android = "{ \"message\" : { \"notification\" : { \"title\" : \"PushDemo\", \"body\" : \"$(alertMessage)\"}, \"data\" : { \"action\" : \"$(alertAction)\" } } }"; public const string iOS = "{ \"aps\" : {\"alert\" : \"$(alertMessage)\"}, \"action\" : \"$(alertAction)\" }"; } public class Silent { public const string Android = "{ \"message\" : { \"data\" : {\"message\" : \"$(alertMessage)\", \"action\" : \"$(alertAction)\"} } }"; public const string iOS = "{ \"aps\" : {\"content-available\" : 1, \"apns-priority\": 5, \"sound\" : \"\", \"badge\" : 0}, \"message\" : \"$(alertMessage)\", \"action\" : \"$(alertAction)\" }"; } }
A classe
PushTemplates
contém cargas úteis de notificação tokenizadas para notificações por push genéricas e silenciosas. Essas cargas úteis são definidas fora do contexto de instalação para permitir a experimentação sem precisar de atualizar as instalações existentes através do serviço. Lidar com alterações em instalações dessa maneira está fora do escopo deste artigo. Em cenários de produto, considere usar modelos personalizados.No Visual Studio, adicione uma nova classe chamada
DeviceInstallation
à pasta Models e substitua seu código pelo seguinte código:using System.ComponentModel.DataAnnotations; namespace PushNotificationsAPI.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>(); }
No Visual Studio, adicione uma nova classe chamada
NotificationRequest
à pasta Models e substitua seu código pelo seguinte código:namespace PushNotificationsAPI.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; } }
No Visual Studio, adicione uma nova classe chamada
NotificationHubOptions
à pasta Models e substitua seu código pelo seguinte código:using System.ComponentModel.DataAnnotations; namespace PushNotificationsAPI.Models; public class NotificationHubOptions { [Required] public string Name { get; set; } [Required] public string ConnectionString { get; set; } }
No Visual Studio, adicione uma nova pasta chamada Services ao seu projeto e, em seguida, adicione uma nova interface chamada
INotificationService
à pasta Services e substitua seu código pelo seguinte código:using PushNotificationsAPI.Models; namespace PushNotificationsAPI.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); }
No Visual Studio, adicione uma nova classe chamada
NotificationHubService
à pasta Services e substitua seu código pelo seguinte código:using Microsoft.Extensions.Options; using Microsoft.Azure.NotificationHubs; using PushNotificationsAPI.Models; namespace PushNotificationsAPI.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.FcmV1).ToLower(), NotificationPlatform.FcmV1 } }; } 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.SendFcmV1NativeNotificationAsync(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.SendFcmV1NativeNotificationAsync(androidPayload, tags, token), _hub.SendAppleNativeNotificationAsync(iOSPayload, tags, token) }; return Task.WhenAll(sendTasks); } }
A expressão de tag fornecida ao método
SendTemplateNotificationsAsync
é limitada a 20 tags se elas contiverem apenas ORs. Caso contrário, eles são limitados a 6 tags. Para obter mais informações, consulte Roteamento e Expressões de Marca.No Visual Studio, abra Program.cs e atualize o código para adicionar o
NotificationHubService
como uma implementação singleton deINotificationService
abaixo da chamada para o métodobuilder.Services.AddAuthentication
:using PushNotificationsAPI.Authentication; using PushNotificationsAPI.Services; using PushNotificationsAPI.Models; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = ApiKeyAuthOptions.DefaultScheme; options.DefaultChallengeScheme = ApiKeyAuthOptions.DefaultScheme; }).AddApiKeyAuth(builder.Configuration.GetSection("Authentication").Bind); builder.Services.AddSingleton<INotificationService, NotificationHubService>(); builder.Services.AddOptions<NotificationHubOptions>() .Configure(builder.Configuration.GetSection("NotificationHub").Bind) .ValidateDataAnnotations(); var app = builder.Build();
Criar a API REST de notificações
Para criar a API REST de notificações:
No Visual Studio, adicione um novo Controller à pasta Controllers, chamado
NotificationsController
.Dica
Escolha o modelo de Controlador de API com ações de leitura/gravação.
No arquivo NotificationsController.cs, adicione as seguintes instruções
using
na parte superior do arquivo:using System.ComponentModel.DataAnnotations; using System.Net; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using PushNotificationsAPI.Models; using PushNotificationsAPI.Services;
No arquivo NotificationsController.cs, adicione o atributo
Authorize
à classeNotificationsController
:[Authorize] [ApiController] [Route("api/[controller]")] public class NotificationsController : ControllerBase
No ficheiro NotificationsController.cs, atualiza o construtor
NotificationsContoller
para aceitar a instância registada deINotificationService
como argumento e atribuí-la a um membro readonly:readonly INotificationService _notificationService; public NotificationsController(INotificationService notificationService) { _notificationService = notificationService; }
No arquivo NotificationsContoller.cs, substitua todos os métodos com o seguinte código:
[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) { // Probably want to ensure deletion even if the connection is broken 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(); }
No arquivo Properties/launchSettings.json, altere a propriedade
launchUrl
para cada perfil deweatherforecast
paraapi/notifications
.
Criar um aplicativo de API
Agora, irá criar uma aplicação API no Serviço de Aplicações do Azure para hospedar o seu serviço de back-end. Isso pode ser feito diretamente do Visual Studio ou do Visual Studio Code, com a CLI do Azure, o Azure PowerShell, a CLI do Desenvolvedor do Azure e por meio do Portal do Azure. Para obter mais informações, consulte Publicar seu aplicativo Web.
Para criar um aplicativo de API no portal do Azure:
Em um navegador web, entre no portal do Azure.
No portal do Azure, clique no botão Criar um recurso e, em seguida, pesquise e escolha Aplicação de API antes de selecionar o botão Criar.
Na página Criar aplicação de API, atualize os seguintes campos antes de selecionar o botão Criar:
Domínio Ação Subscrição 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. Nome Insira um nome globalmente exclusivo. Pilha de tempo de execução Verifique se a versão mais recente do .NET está selecionada. Depois de providenciado o API App, navegue para o recurso específico.
Na página Visão Geral, anote o valor de domínio padrão. Esta URL é o endereço de back-end que será consumido pela sua aplicação .NET MAUI. A URL usará o nome do aplicativo de API que você especificou, com o formato
https://<app_name>.azurewebsites.net
.No portal do Azure, navegue até o painel Definições > Variáveis de ambiente e verifique se a guia Configurações do aplicativo está selecionada. Em seguida, use o botão Adicionar para adicionar as seguintes configurações:
Nome Valor Autenticação:ApiKey <api_key_value> NotificationHub:Nome <hub_name_value> NotificationHub:ConnectionString <hub_connection_string_value> Importante
A definição de aplicação
Authentication:ApiKey
foi adicionada para maior simplicidade. Para cenários de produção, considere um serviço como do Azure KeyVault para armazenar com segurança a cadeia de conexão.Depois que todas essas configurações tiverem sido inseridas, selecione o botão Aplicar e, em seguida, o botão Confirmar.
Publicar o serviço de back-end
Para publicar seu serviço de back-end no Serviço de Aplicativo do Azure:
- No Visual Studio, clique com o botão direito do mouse em seu projeto e selecione Publicar.
- No assistente Publicar, selecione Azure e, em seguida, o botão Avançar.
- No assistente Publicar, selecione do Serviço de Aplicativo do Azure (Windows) e, em seguida, o botão Próxima.
- No assistente Publicar, siga o fluxo de autenticação para conectar o Visual Studio à sua assinatura do Azure e publicar o aplicativo.
O Visual Studio cria, empacota e publica o aplicativo no Azure e, em seguida, inicia o aplicativo em seu navegador padrão. Para obter mais informações, consulte Publicar um aplicativo Web ASP.NET.
Dica
Você pode baixar um perfil de publicação para o seu aplicativo no painel Visão Geral do seu aplicativo de API no portal do Azure e, em seguida, usar o perfil no Visual Studio para publicar o seu aplicativo.
Validar a API publicada
Para verificar se o aplicativo de API foi publicado corretamente, você deve usar as ferramentas REST de sua escolha para enviar uma solicitação de POST
para o seguinte endereço:
https://<app_name>.azurewebsites.net/api/notifications/requests
Observação
O endereço base é https://<app_name>.azurewebsites.net
.
Certifique-se de configurar os cabeçalhos de solicitação para incluir a chave apikey
e o seu respetivo valor, defina o corpo como não formatado e use o seguinte conteúdo JSON como espaço reservado:
{}
Você deve receber uma resposta 400 Bad Request
do serviço.
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 .NET MAUI.
Para obter mais informações sobre como chamar APIs REST, consulte Usar arquivos .http no Visual Studio e Testar APIs da Web com o Http Repl. No Visual Studio Code, REST Client pode ser usado para testar APIs REST.
Criar um aplicativo .NET MAUI
Nesta seção, você criará um aplicativo .NET Multi-platform App UI (.NET MAUI) que permite que você se registre para receber notificações por push de um hub de notificação por meio do serviço de back-end e cancele o registro.
Para criar seu aplicativo .NET MAUI:
No Visual Studio, crie um novo aplicativo .NET MAUI chamado PushNotificationsDemo, usando o .NET MAUI App modelo de projeto.
No Visual Studio, adicione uma nova pasta chamada Models ao projeto .NET MAUI e, em seguida, adicione uma nova classe chamada
DeviceInstallation
à pasta Models e substitua seu código pelo seguinte código:using System.Text.Json.Serialization; namespace PushNotificationsDemo.Models; public class DeviceInstallation { [JsonPropertyName("installationId")] public string InstallationId { get; set; } [JsonPropertyName("platform")] public string Platform { get; set; } [JsonPropertyName("pushChannel")] public string PushChannel { get; set; } [JsonPropertyName("tags")] public List<string> Tags { get; set; } = new List<string>(); }
No Visual Studio, adicione uma enumeração chamada
PushDemoAction
à pasta Models e substitua seu código pelo seguinte código:namespace PushNotificationsDemo.Models; public enum PushDemoAction { ActionA, ActionB }
No Visual Studio, adicione uma nova pasta chamada Services ao projeto .NET MAUI e, em seguida, adicione uma nova interface chamada
IDeviceInstallationService
à pasta Services e substitua seu código pelo seguinte código:using PushNotificationsDemo.Models; namespace PushNotificationsDemo.Services; public interface IDeviceInstallationService { string Token { get; set; } bool NotificationsSupported { get; } string GetDeviceId(); DeviceInstallation GetDeviceInstallation(params string[] tags); }
Esta interface será implementada em cada plataforma posteriormente, para fornecer as informações
DeviceInstallation
exigidas pelo serviço de back-end.No Visual Studio, adicione uma interface chamada
INotificationRegistrationService
à pasta Services e substitua seu código pelo seguinte código:namespace PushNotificationsDemo.Services; public interface INotificationRegistrationService { Task DeregisterDeviceAsync(); Task RegisterDeviceAsync(params string[] tags); Task RefreshRegistrationAsync(); }
Essa interface lidará com a interação entre o cliente e o serviço de back-end.
No Visual Studio, adicione uma interface chamada
INotificationActionService
à pasta Services e substitua seu código pelo seguinte código:namespace PushNotificationsDemo.Services; public interface INotificationActionService { void TriggerAction(string action); }
Esta interface será usada como um mecanismo simples para centralizar o tratamento das ações de notificação.
No Visual Studio, adicione uma interface chamada
IPushDemoNotificationActionService
à pasta Services e substitua seu código pelo seguinte código:using PushNotificationsDemo.Models; namespace PushNotificationsDemo.Services; public interface IPushDemoNotificationActionService : INotificationActionService { event EventHandler<PushDemoAction> ActionTriggered; }
O tipo
IPushDemoNotificationActionService
é específico desta aplicação e usa a enumeraçãoPushDemoAction
para identificar a ação a ser acionada usando uma abordagem fortemente tipada.No Visual Studio, adicione uma classe chamada
NotificationRegistrationService
à pasta Services e substitua seu código pelo seguinte código:using System.Text; using System.Text.Json; using PushNotificationsDemo.Models; namespace PushNotificationsDemo.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; IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = Application.Current.Windows[0].Page.Handler.MauiContext.Services.GetService<IDeviceInstallationService>()); public NotificationRegistrationService(string baseApiUri, string apiKey) { _client = new HttpClient(); _client.DefaultRequestHeaders.Add("Accept", "application/json"); _client.DefaultRequestHeaders.Add("apikey", apiKey); _baseApiUrl = baseApiUri; } 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, JsonSerializer.Serialize(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 = JsonSerializer.Deserialize<string[]>(serializedTags); await RegisterDeviceAsync(tags); } async Task SendAsync<T>(HttpMethod requestType, string requestUri, T obj) { string serializedContent = null; await Task.Run(() => serializedContent = JsonSerializer.Serialize(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(); } }
No Visual Studio, adicione uma classe chamada
PushDemoNotificationActionService
à pasta Services e substitua seu código pelo seguinte código:using PushNotificationsDemo.Models; namespace PushNotificationsDemo.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); } }
No Visual Studio, adicione uma classe chamada
Config
à raiz do projeto e substitua seu código pelo seguinte código:namespace PushNotificationsDemo; public static partial class Config { public static string ApiKey = "API_KEY"; public static string BackendServiceEndpoint = "BACKEND_SERVICE_ENDPOINT"; }
A classe
Config
é usada como uma maneira simples de manter seus 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.Importante
Ao especificar o endereço base no aplicativo .NET MAUI, certifique-se de que ele termine com um
/
.No Visual Studio, adicione uma classe chamada
Config.local_secrets
à raiz do projeto. Em seguida, substitua o código no arquivo Config.local_secrets.cs com o seguinte código:namespace PushNotificationsDemo; public static partial class Config { static Config() { ApiKey = "<your_api_key>"; BackendServiceEndpoint = "<your_api_app_url>"; } }
Substitua os valores de marcador pelos valores escolhidos ao criar o serviço de back-end. O URL
BackendServiceEndpoint
deve usar o formatohttps://<api_app_name>.azurewebsites.net/
.Dica
Lembre-se de adicionar
*.local_secrets.*
ao seu arquivo.gitignore
para evitar comprometer esse arquivo com o controle do código-fonte.
Criar a interface do usuário
Para criar a interface do usuário do aplicativo:
No Visual Studio, abra MainPage.xaml e substitua o
VerticalStackLayout
e seus filhos pelo seguinte XAML:<VerticalStackLayout Margin="20" Spacing="6"> <Button x:Name="registerButton" Text="Register" Clicked="OnRegisterButtonClicked" /> <Button x:Name="deregisterButton" Text="Deregister" Clicked="OnDeregisterButtonClicked" /> </VerticalStackLayout>
No Visual Studio, abra MainPage.xaml.cs e adicione uma instrução
using
para o namespacePushNotificationsDemo.Services
:using PushNotificationsDemo.Services;
No arquivo MainPage.xaml.cs, adicione um campo de apoio
readonly
para armazenar uma referência à implementaçãoINotificationRegistrationService
.readonly INotificationRegistrationService _notificationRegistrationService;
No construtor
MainPage
, resolva a implementaçãoINotificationRegistrationService
e atribua-a ao campo de suporte_notificationRegistrationService
:public MainPage(INotificationRegistrationService service) { InitializeComponent(); _notificationRegistrationService = service; }
Na classe
MainPage
, implemente os manipuladores de eventosOnRegisterButtonClicked
eOnDeregisterButtonClicked
, chamando os métodos de registro e cancelamento de registro correspondentes no objetoINotificationRegistrationService
:void OnRegisterButtonClicked(object sender, EventArgs e) { _notificationRegistrationService.RegisterDeviceAsync() .ContinueWith((task) => { ShowAlert(task.IsFaulted ? task.Exception.Message : $"Device registered"); }); } void OnDeregisterButtonClicked(object sender, EventArgs e) { _notificationRegistrationService.DeregisterDeviceAsync() .ContinueWith((task) => { ShowAlert(task.IsFaulted ? task.Exception.Message : $"Device deregistered"); }); } void ShowAlert(string message) { MainThread.BeginInvokeOnMainThread(() => { DisplayAlert("Push notifications demo", message, "OK") .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }); }); }
void OnRegisterButtonClicked(object sender, EventArgs e) { _notificationRegistrationService.RegisterDeviceAsync() .ContinueWith((task) => { ShowAlert(task.IsFaulted ? task.Exception.Message : $"Device registered"); }); } void OnDeregisterButtonClicked(object sender, EventArgs e) { _notificationRegistrationService.DeregisterDeviceAsync() .ContinueWith((task) => { ShowAlert(task.IsFaulted ? task.Exception.Message : $"Device deregistered"); }); } void ShowAlert(string message) { MainThread.BeginInvokeOnMainThread(() => { DisplayAlertAsync("Push notifications demo", message, "OK") .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }); }); }
Importante
No aplicativo, o registro e cancelamento de registro é realizado em resposta à entrada do usuário, para permitir que essa funcionalidade seja explorada e testada mais facilmente. Em um aplicativo de produção, você normalmente executaria as ações de registro e cancelamento de registro durante o ponto apropriado do ciclo de vida do aplicativo, sem exigir a entrada explícita do usuário.
No Visual Studio, abra App.xaml.cs e adicione as seguintes instruções
using
:using PushNotificationsDemo.Models; using PushNotificationsDemo.Services;
No App.xaml.cs, adicione um
readonly
campo de suporte para armazenar uma referência à implementaçãoIPushDemoNotificationActionService
:readonly IPushDemoNotificationActionService _actionService;
No construtor
App
, resolva a implementaçãoIPushDemoNotificationActionService
e atribua-a ao campo de suporte_actionService
e inscreva-se no eventoIPushDemoNotificationActionService.ActionTriggered
:public App(IPushDemoNotificationActionService service) { InitializeComponent(); _actionService = service; _actionService.ActionTriggered += NotificationActionTriggered; MainPage = new AppShell(); }
No construtor
App
, resolva a implementaçãoIPushDemoNotificationActionService
e atribua-a ao campo de suporte_actionService
e inscreva-se no eventoIPushDemoNotificationActionService.ActionTriggered
:public App(IPushDemoNotificationActionService service) { InitializeComponent(); _actionService = service; _actionService.ActionTriggered += NotificationActionTriggered; }
Na classe
App
, implemente o manipulador de eventos para o eventoIPushDemoNotificationActionService.ActionTriggered
:void NotificationActionTriggered(object sender, PushDemoAction e) { ShowActionAlert(e); } void ShowActionAlert(PushDemoAction action) { MainThread.BeginInvokeOnMainThread(() => { Windows[0].Page?.DisplayAlert("Push notifications demo", $"{action} action received.", "OK") .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }); }); }
void NotificationActionTriggered(object sender, PushDemoAction e) { ShowActionAlert(e); } void ShowActionAlert(PushDemoAction action) { MainThread.BeginInvokeOnMainThread(() => { Windows[0].Page?.DisplayAlertAsync("Push notifications demo", $"{action} action received.", "OK") .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }); }); }
O manipulador de eventos para o evento
ActionTriggered
demonstra o recebimento e a propagação de ações de notificação por push. Normalmente, estes são tratados silenciosamente, por exemplo, navegando para uma vista específica ou atualizando alguns dados em vez de apresentar um alerta.
Configurar a aplicação Android
Para configurar seu aplicativo .NET MAUI no Android para receber e processar notificações por push:
No Visual Studio, adicione o pacote NuGet Xamarin.Firebase.Messaging ao seu projeto de aplicação .NET MAUI.
No Visual Studio, adicione seu arquivo google-services.json à pasta Platforms/Android do seu projeto de aplicativo .NET MAUI. Uma vez que o arquivo foi adicionado ao seu projeto, ele deve ter sido adicionado com uma ação de compilação de
GoogleServicesJson
:<ItemGroup Condition="'$(TargetFramework)' == 'net8.0-android'"> <GoogleServicesJson Include="Platforms\Android\google-services.json" /> </ItemGroup>
Dica
Lembre-se de adicionar
google-services.json
ao seu arquivo.gitignore
para evitar comprometer esse arquivo com o controle do código-fonte.No Visual Studio, edite o arquivo de projeto (*.csproj) e defina o
SupportedOSPlatformVersion
para Android como 26.0:<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">26.0</SupportedOSPlatformVersion>
O Google fez alterações nos canais de notificação do Android na API 26. Para mais informações, consulte a seção Canais de notificação no site developer.android.com.
Na pasta Platforms/Android do projeto, adicione uma nova classe chamada
DeviceInstallationService
e substitua seu código pelo seguinte código:using Android.Gms.Common; using PushNotificationsDemo.Models; using PushNotificationsDemo.Services; using static Android.Provider.Settings; namespace PushNotificationsDemo.Platforms.Android; public class DeviceInstallationService : IDeviceInstallationService { public string Token { get; set; } public bool NotificationsSupported => GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(Platform.AppContext) == ConnectionResult.Success; public string GetDeviceId() => Secure.GetString(Platform.AppContext.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 FCMv1."); var installation = new DeviceInstallation { InstallationId = GetDeviceId(), Platform = "fcmv1", PushChannel = Token }; installation.Tags.AddRange(tags); return installation; } string GetPlayServicesError() { int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(Platform.AppContext); if (resultCode != ConnectionResult.Success) return GoogleApiAvailability.Instance.IsUserResolvableError(resultCode) ? GoogleApiAvailability.Instance.GetErrorString(resultCode) : "This device isn't supported."; return "An error occurred preventing the use of push notifications."; } }
Esta classe fornece um ID exclusivo, usando o valor
Secure.AndroidId
e o payload de registo do hub de notificações.Na pasta Platforms/Android do projeto, adicione uma nova classe chamada
PushNotificationFirebaseMessagingService
e substitua seu código pelo seguinte código:using Android.App; using Firebase.Messaging; using PushNotificationsDemo.Services; namespace PushNotificationsDemo.Platforms.Android; [Service(Exported = false)] [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })] public class PushNotificationFirebaseMessagingService : FirebaseMessagingService { IPushDemoNotificationActionService _notificationActionService; INotificationRegistrationService _notificationRegistrationService; IDeviceInstallationService _deviceInstallationService; int _messageId; IPushDemoNotificationActionService NotificationActionService => _notificationActionService ?? (_notificationActionService = IPlatformApplication.Current.Services.GetService<IPushDemoNotificationActionService>()); INotificationRegistrationService NotificationRegistrationService => _notificationRegistrationService ?? (_notificationRegistrationService = IPlatformApplication.Current.Services.GetService<INotificationRegistrationService>()); IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = IPlatformApplication.Current.Services.GetService<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) { base.OnMessageReceived(message); if (message.Data.TryGetValue("action", out var messageAction)) NotificationActionService.TriggerAction(messageAction); } }
Esta classe tem um atributo
IntentFilter
que inclui o filtrocom.google.firebase.MESSAGING_EVENT
. Esse filtro permite que o Android passe mensagens recebidas para essa classe para processamento.Para obter informações sobre o formato de mensagens do Firebase Cloud Messaging, consulte Sobre mensagens do FCM no developer.android.com.
No Visual Studio, abra o arquivo MainActivity.cs na pasta Platforms/Android e adicione as seguintes instruções
using
:using Android.App; using Android.Content; using Android.Content.PM; using Android.OS; using PushNotificationsDemo.Services; using Firebase.Messaging;
Na classe
MainActivity
, defina oLaunchMode
comoSingleTop
para que oMainActivity
não seja criado novamente quando aberto:[Activity( Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
Na classe
MainActivity
, adicione campos de suporte para armazenar referências às implementaçõesIPushDemoNotificationActionService
eIDeviceInstallationService
:IPushDemoNotificationActionService _notificationActionService; IDeviceInstallationService _deviceInstallationService;
Na classe
MainActivity
, adicione propriedades privadasNotificationActionService
eDeviceInstallationService
que obtêm as suas implementações concretas do contêiner de injeção de dependência do aplicativo.IPushDemoNotificationActionService NotificationActionService => _notificationActionService ?? (_notificationActionService = IPlatformApplication.Current.Services.GetService<IPushDemoNotificationActionService>()); IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = IPlatformApplication.Current.Services.GetService<IDeviceInstallationService>());
Na classe
MainActivity
, implemente a interfaceAndroid.Gms.Tasks.IOnSuccessListener
para recuperar e armazenar o token do Firebase:public class MainActivity : MauiAppCompatActivity, Android.Gms.Tasks.IOnSuccessListener { public void OnSuccess(Java.Lang.Object result) { DeviceInstallationService.Token = result.ToString(); } }
Na classe
MainActivity
, adicione o métodoProcessNotificationActions
que verificará se um determinadoIntent
tem um valor extra chamadoaction
e, em seguida, acione condicionalmente esseaction
usando a implementaçãoIPushDemoNotificationActionService
:void ProcessNotificationsAction(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); } }
Na classe
MainActivity
, substitua o métodoOnNewIntent
para chamar o métodoProcessNotificationActions
:protected override void OnNewIntent(Intent? intent) { base.OnNewIntent(intent); ProcessNotificationsAction(intent); }
Como o
LaunchMode
para oActivity
está definido comoSingleTop
, umIntent
será enviado para a instância deActivity
existente por meio da substituição deOnNewIntent
, em vez do métodoOnCreate
. Portanto, deve-se lidar com uma intenção recebida emOnNewIntent
eOnCreate
.Na classe
MainActivity
, substitua o métodoOnCreate
para chamar o métodoProcessNotificationActions
e recuperar o token do Firebase, adicionandoMainActivity
como oIOnSuccessListener
:protected override void OnCreate(Bundle? savedInstanceState) { base.OnCreate(savedInstanceState); if (DeviceInstallationService.NotificationsSupported) FirebaseMessaging.Instance.GetToken().AddOnSuccessListener(this); ProcessNotificationsAction(Intent); }
Observação
A aplicação deve ser registada novamente cada vez que o utilizador a executa e a interrompe a partir de uma sessão de depuração para continuar a receber notificações push.
No Visual Studio, adicione a permissão
POST_NOTIFICATIONS
ao arquivo AndroidManifest.xml na pasta Platforms/Android:<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
Para obter mais informações sobre esta permissão, consulte permissões de tempo de execução de notificação no developer.android.com.
No Visual Studio, abra MainPage.xaml.cs e adicione o seguinte código à classe
MainPage
:#if ANDROID protected override async void OnAppearing() { base.OnAppearing(); PermissionStatus status = await Permissions.RequestAsync<Permissions.PostNotifications>(); } #endif
Esse código é executado no Android quando o
MainPage
aparece e solicita que o usuário conceda a permissão dePOST_NOTIFICATIONS
. Para obter mais informações sobre permissões do .NET MAUI, consulte Permissions.
Configurar a aplicação iOS
O simulador iOS suporta notificações remotas no iOS 16+ quando executado no macOS 13+ em computadores Mac com processadores de silício ou T2 da Apple. Cada simulador gera tokens de registro que são exclusivos para a combinação desse simulador e do hardware do Mac em que ele está sendo executado.
Importante
O simulador suporta o ambiente sandbox do Apple Push Notification Service.
As instruções a seguir pressupõem que você esteja usando um hardware compatível com o recebimento de notificações remotas em um simulador do iOS. Se esse não for o caso, você terá que executar o aplicativo iOS em um dispositivo físico, o que exigirá que você crie um perfil de provisionamento para seu aplicativo que inclua o recurso de Notificações por Push. Em seguida, você precisará garantir que seu aplicativo seja criado usando seu perfil de certificado e provisionamento. Para obter mais informações sobre como fazer isso, consulte Configurar seu aplicativo iOS para funcionar com os Hubs de Notificação do Azuree siga as instruções abaixo.
Para configurar seu aplicativo .NET MAUI no iOS para receber e processar notificações por push:
No Visual Studio, edite o arquivo de projeto (*.csproj) e defina o
SupportedOSPlatformVersion
para iOS como 13.0:<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">13.0</SupportedOSPlatformVersion>
A Apple fez alterações em seu serviço de push no iOS 13. Para mais informações, consulte atualizações do Azure Notification Hubs para iOS 13.
No Visual Studio, adicione um ficheiro Entitlements.plist à pasta Platforms/iOS do projeto e adicione o seguinte XML ao ficheiro:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>aps-environment</key> <string>development</string> </dict> </plist>
Isto configura a concessão do ambiente APS e especifica o uso do ambiente de desenvolvimento do serviço Apple Push Notification. Em aplicações de produção, esse valor de permissão deve ser definido como
production
. Para obter mais informações sobre esse direito, consulte APS Environment Entitlement on developer.apple.com.Para obter mais informações sobre como adicionar um ficheiro de permissões, consulte permissões do iOS.
No Visual Studio, adicione uma nova classe chamada
DeviceInstallationService
à pasta Platforms/iOS do projeto e adicione o seguinte código ao arquivo:using PushNotificationsDemo.Services; using PushNotificationsDemo.Models; using UIKit; namespace PushNotificationsDemo.Platforms.iOS; 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"; } }
Essa classe fornece uma ID exclusiva, usando o valor
UIDevice.IdentifierForVendor
e a carga útil de registro do hub de notificação.No Visual Studio, adicione uma nova classe chamada
NSDataExtensions
à pasta Platforms/iOS do projeto e adicione o seguinte código ao arquivo:using Foundation; using System.Text; namespace PushNotificationsDemo.Platforms.iOS; 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(); } }
O método de extensão
ToHexString
será consumido pelo código que você adicionará que analisa o token de dispositivo recuperado.No Visual Studio, abra o arquivo AppDelegate.cs na pasta Platforms/iOS e adicione as seguintes instruções
using
:using System.Diagnostics; using Foundation; using PushNotificationsDemo.Platforms.iOS; using PushNotificationsDemo.Services; using UIKit; using UserNotifications;
Na classe
AppDelegate
, adicione campos de suporte para armazenar referências às implementaçõesIPushDemoNotificationActionService
,INotificationRegistrationService
eIDeviceInstallationService
:IPushDemoNotificationActionService _notificationActionService; INotificationRegistrationService _notificationRegistrationService; IDeviceInstallationService _deviceInstallationService;
Na classe
AppDelegate
, adicioneNotificationActionService
,NotificationRegistrationService
eDeviceInstallationService
propriedades privadas que recuperam suas implementações concretas do contêiner de injeção de dependência do aplicativo:IPushDemoNotificationActionService NotificationActionService => _notificationActionService ?? (_notificationActionService = IPlatformApplication.Current.Services.GetService<IPushDemoNotificationActionService>()); INotificationRegistrationService NotificationRegistrationService => _notificationRegistrationService ?? (_notificationRegistrationService = IPlatformApplication.Current.Services.GetService<INotificationRegistrationService>()); IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = IPlatformApplication.Current.Services.GetService<IDeviceInstallationService>());
Na classe
AppDelegate
, adicione o métodoCompleteRegistrationAsync
para definir o valor da propriedadeIDeviceInstallationService.Token
:Task CompleteRegistrationAsync(NSData deviceToken) { DeviceInstallationService.Token = deviceToken.ToHexString(); return NotificationRegistrationService.RefreshRegistrationAsync(); }
Esse método também atualiza o registro e armazena em cache o token do dispositivo se ele tiver sido atualizado desde a última vez que foi armazenado.
Na classe
AppDelegate
, adicione o métodoProcessNotificationActions
para processar os dados de notificaçãoNSDictionary
e chamar condicionalmenteNotificationActionService.TriggerAction
:void ProcessNotificationActions(NSDictionary userInfo) { if (userInfo == null) return; try { // If your app isn't in the foreground, the notification goes to Notification Center. // If your app is in the foreground, the notification goes directly to your app and you // need to process the notification payload yourself. 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); } }
Na classe
AppDelegate
, adicione o métodoRegisteredForRemoteNotifications
passando o argumentodeviceToken
para o métodoCompleteRegistrationAsync
:[Export("application:didRegisterForRemoteNotificationsWithDeviceToken:")] public void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken) { CompleteRegistrationAsync(deviceToken) .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }); }
Esse método será chamado quando o aplicativo for registrado para receber notificação remota e for usado para solicitar o token de dispositivo exclusivo, que é efetivamente o endereço do seu aplicativo no dispositivo.
Na classe
AppDelegate
, adicione o métodoReceivedRemoteNotification
passando o argumentouserInfo
para o métodoProcessNotificationActions
:[Export("application:didReceiveRemoteNotification:")] public void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo) { ProcessNotificationActions(userInfo); }
Esse método será chamado quando o aplicativo receber uma notificação remota e for usado para processar a notificação.
Na classe
AppDelegate
, adicione o métodoFailedToRegisterForRemoteNotifications
para registrar quaisquer erros:[Export("application:didFailToRegisterForRemoteNotificationsWithError:")] public void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error) { Debug.WriteLine(error.Description); }
Esse método será chamado quando o aplicativo não conseguir se registrar para receber notificações remotas. O registro pode falhar se o dispositivo não estiver conectado à rede, se o servidor APNS estiver inacessível ou se o aplicativo estiver configurado incorretamente.
Observação
Para cenários de produção, convém implementar o registro em log e o tratamento de erros adequados no método
FailedToRegisterForRemoteNotifications
.Na classe
AppDelegate
, adicione o métodoFinishedLaunching
para solicitar condicionalmente permissão para usar notificações e registrar-se para notificações remotas:[Export("application:didFinishLaunchingWithOptions:")] public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) { if (DeviceInstallationService.NotificationsSupported) { UNUserNotificationCenter.Current.RequestAuthorization( UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound, (approvalGranted, error) => { if (approvalGranted && error == null) { MainThread.BeginInvokeOnMainThread(() => { UIApplication.SharedApplication.RegisterForRemoteNotifications(); }); } }); } using (var userInfo = launchOptions?.ObjectForKey(UIApplication.LaunchOptionsRemoteNotificationKey) as NSDictionary) { ProcessNotificationActions(userInfo); } return base.FinishedLaunching(application, launchOptions); }
Para obter informações sobre como pedir permissão para usar notificações, consulte Pedindo permissão para usar notificações no developer.apple.com.
Para obter informações sobre notificações no iOS, consulte Notificações de Usuário no developer.apple.com.
Registrar tipos com o contêiner de injeção de dependência do aplicativo
No Visual Studio, abra MauiProgram.cs e adicione uma instrução
using
para o namespacePushNotificationsDemo.Services
:using PushNotificationsDemo.Services;
Na classe
MauiProgram
, adicione código para o método de extensãoRegisterServices
que registra oDeviceInstallationService
em cada plataforma e os serviços dePushDemoNotificationActionService
eNotificationRegistrationService
entre plataformas e que retorna um objetoMauiAppBuilder
:public static MauiAppBuilder RegisterServices(this MauiAppBuilder builder) { #if IOS builder.Services.AddSingleton<IDeviceInstallationService, PushNotificationsDemo.Platforms.iOS.DeviceInstallationService>(); #elif ANDROID builder.Services.AddSingleton<IDeviceInstallationService, PushNotificationsDemo.Platforms.Android.DeviceInstallationService>(); #endif builder.Services.AddSingleton<IPushDemoNotificationActionService, PushDemoNotificationActionService>(); builder.Services.AddSingleton<INotificationRegistrationService>(new NotificationRegistrationService(Config.BackendServiceEndpoint, Config.ApiKey)); return builder; }
Na classe
MauiProgram
, adicione código para o método de extensãoRegisterViews
que registra o tipoMainPage
como um singleton e que retorna um objetoMauiAppBuilder
:public static MauiAppBuilder RegisterViews(this MauiAppBuilder builder) { builder.Services.AddSingleton<MainPage>(); return builder; }
O tipo
MainPage
é registrado porque requer uma dependênciaINotificationRegistrationService
e todos os tipos que exigem uma dependência devem ser registrados com o contêiner de injeção de dependência.Na classe
MauiProgram
, modifique o métodoCreateMauiApp
para que ele chame os métodos de extensãoRegisterServices
eRegisterViews
:public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); }) .RegisterServices() .RegisterViews(); #if DEBUG builder.Logging.AddDebug(); #endif return builder.Build(); }
Para obter mais informações sobre a injeção de dependência no .NET MAUI, consulte Injeção de Dependência.
Testar a aplicação
Você pode testar seu aplicativo enviando notificações por push para o aplicativo usando o serviço de back-end ou por meio do portal do Azure.
O simulador iOS suporta notificações remotas no iOS 16+ quando executado no macOS 13+ em computadores Mac com processadores de silício ou T2 da Apple. Se você não atender a esses requisitos de hardware, terá que testar seu aplicativo iOS em um dispositivo físico. No Android, você pode testar seu aplicativo em um dispositivo físico desbloqueado pelo desenvolvedor ou em um emulador.
Android e iOS exibem notificações por push em nome do aplicativo quando ele está sendo executado em segundo plano. Se o aplicativo estiver sendo executado em primeiro plano quando a notificação for recebida, o código do aplicativo determinará o comportamento. Por exemplo, você pode atualizar a interface do seu aplicativo para refletir as novas informações contidas na notificação.
Teste usando o serviço de back-end
Para enviar uma notificação por push de teste para seu aplicativo por meio do serviço de back-end publicado no Serviço de Aplicativo do Azure:
No Visual Studio, execute o aplicativo PushNotificationsDemo no Android ou iOS e selecione o botão Registrar.
Observação
Se você estiver testando no Android, certifique-se de que não está executando usando a configuração de depuração. Como alternativa, se o aplicativo tiver sido implantado anteriormente, certifique-se de que ele foi fechado à força e, em seguida, inicie-o novamente a partir do iniciador.
Nas ferramentas REST de sua escolha, envie uma solicitação de
POST
para o seguinte endereço:https://<app_name>.azurewebsites.net/api/notifications/requests
Certifique-se de configurar os cabeçalhos de solicitação para incluir a chave
apikey
e seu valor, definir o corpo como "raw" e usar o seguinte conteúdo JSON:{ "text": "Message from REST tooling!", "action": "action_a" }
O pedido global deve ser semelhante ao seguinte exemplo:
POST /api/notifications/requests HTTP/1.1 Host: https://<app_name>.azurewebsites.net apikey: <your_api_key> Content-Type: application/json { "text": "Message from REST tooling!", "action": "action_a" }
Nas ferramentas REST de sua escolha, valide se você recebeu uma resposta 200 OK.
No aplicativo no Android ou iOS, deve aparecer um alerta mostrando ação ActionA recebida.
Para obter mais informações sobre como chamar APIs REST, consulte Usar arquivos .http no Visual Studio e Testar APIs da Web com o Http Repl. No Visual Studio Code, de cliente REST pode ser usada para testar APIs REST.
Teste usando o portal do Azure
Os Hubs de Notificação do Azure permitem que você verifique se seu aplicativo pode receber notificações por push.
Para enviar uma notificação por push de teste para seu aplicativo por meio do portal do Azure:
No Visual Studio, execute o aplicativo PushNotificationsDemo no Android ou iOS e selecione o botão Registrar.
Observação
Se estiveres a testar no Android, assegura-te de que não estás a executar usando a configuração de depuração. Como alternativa, se o aplicativo tiver sido implantado anteriormente, certifique-se de que ele foi fechado à força e, em seguida, inicie-o novamente a partir do iniciador.
No portal Azure, navegue até ao hub de notificações e selecione o botão Teste de Envio na folha Visão Geral.
Na folha Test Send, selecione o de plataforma necessário e modifique a carga útil.
Para a Apple, use a seguinte carga útil:
{ "aps": { "alert": "Message from Notification Hub!" }, "action": "action_a" }
Para Android, use o seguinte payload:
{ "message": { "notification": { "title": "PushDemo", "body": "Message from Notification Hub!" }, "data": { "action": "action_a" } } }
O portal do Azure deve indicar que a notificação foi enviada com êxito.
Para obter informações sobre o formato de mensagem do Firebase Cloud Messaging, consulte Sobre mensagens do FCM no developer.android.com.
No aplicativo no Android ou iOS, deve aparecer um alerta mostrando ação ActionA recebida.
Solução de problemas
As seções a seguir discutem os problemas comuns encontrados ao tentar consumir notificações por push em um aplicativo cliente.
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 estiver testando no aplicativo de API do Azure, verifique se o serviço está em execução e foi implantado e iniciado sem erros.
Certifique-se de ter especificado o endereço base corretamente em suas ferramentas REST ou na configuração do aplicativo .NET MAUI. O endereço base deve ser https://<api_name>.azurewebsites.net
ou https://localhost:7020
ao testar localmente.
Recebendo um código de status 401 do serviço de back-end
Valide se você está definindo o cabeçalho da solicitação apikey
corretamente e se 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 definida em seu aplicativo .NET MAUI corresponde ao valor Authentication:ApiKey
segredos de usuário usado pelo serviço de back-end.
Se você estiver testando com um aplicativo de API do Azure, verifique se o valor da chave definido em seu aplicativo .NET MAUI corresponde ao valor de configuração de aplicativo Authentication:ApiKey
definido no portal do Azure. Se você criou ou alterou essa configuração de aplicativo depois de implantar o serviço de back-end, deverá reiniciar o serviço para que o valor entre em vigor.
Recebendo um código de status 404 do serviço de back-end
Valide se o ponto de extremidade e o método HTTP estão corretos:
- PUT -
https://<api_name>.azurewebsites.net/api/notifications/installations
- EXCLUIR -
https://<api_name>.azurewebsites.net/api/notifications/installations/<installation_id>
- CORREIO -
https://<api_name>.azurewebsites.net/api/notifications/requests
Ou ao testar localmente:
- PUT -
https://localhost:7020/api/notifications/installations
- EXCLUIR -
https://localhost:7020/api/notifications/installations/<installation_id>
- PUBLICAÇÃO -
https://localhost:7020/api/notifications/requests
Importante
Ao especificar o endereço base no aplicativo .NET MAUI, certifique-se de que ele termine com um /
. O endereço base deve ser https://<api_name>.azurewebsites.net
ou https://localhost:7020/
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 sempre que iniciar uma sessão de depuração. O depurador fará com que um novo token do Firebase seja gerado e, portanto, a instalação do hub de notificação deve ser atualizada.
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 a propriedade StatusCode
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 códigos de status específicos para a respetiva API. Em seguida, tente chamar o serviço de back-end ao depurar o código localmente.
Valide se o serviço de back-end está funcionando conforme o esperado pelas ferramentas REST de sua escolha e use a carga criada pelo aplicativo .NET MAUI para a plataforma escolhida.
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 a ser resolvidos para as variáveis InstallationId
e Token
na plataforma escolhida.
Não é possível resolver um ID para o dispositivo a mensagem de erro do dispositivo
Revise as seções de configuração específicas da plataforma para garantir que nenhuma etapa tenha sido perdida.