Esercitazione: Inviare notifiche push alle app MAUI .NET usando Hub di notifica di Azure tramite un servizio back-end
Le notifiche push recapitano informazioni da un sistema back-end a un'app client. Apple, Google e altre piattaforme dispongono di un proprio servizio PNS (Push Notification Service). Hub di notifica di Azure consente di centralizzare le notifiche tra piattaforme in modo che l'app back-end possa comunicare con un singolo hub, che si occupa della distribuzione delle notifiche a ogni PNS.
Hub di notifica di Azure richiede che le app si registrino con l'hub e, facoltativamente, definisci modelli e/o sottoscrivono i tag:
- L'esecuzione di un'installazione del dispositivo collega un handle PNS a un identificatore nell'hub di notifica di Azure. Per altre informazioni sulle registrazioni, vedere Gestione della registrazione.
- I modelli consentono ai dispositivi di specificare modelli di messaggio con parametri. I messaggi in arrivo possono essere personalizzati per ogni dispositivo. Per altre informazioni, vedere Modelli di Hub di notifica.
- I tag possono essere usati per sottoscrivere categorie di messaggi come notizie, sport e meteo. Per altre informazioni, vedere Routing ed espressioni tag.
In questa esercitazione si useranno Hub di notifica di Azure per inviare notifiche push a un'app .NET multipiattaforma (.NET MAUI) destinata ad Android e iOS. Un back-end dell'API Web core ASP.NET viene usato per gestire la registrazione del dispositivo per il client e per avviare una notifica push. Queste operazioni vengono gestite usando il pacchetto NuGet Microsoft.Azure.NotificationHubs . Per altre informazioni sull'approccio generale, vedere Gestione della registrazione da un back-end.
In questa esercitazione:
- Configurare i servizi di notifica push e l'hub di notifica di Azure.
- Creare un'app back-end WebAPI core ASP.NET.
- Creare un'app .NET MAUI.
- Configurare l'app Android per le notifiche push.
- Configurare l'app iOS per le notifiche push.
- Test dell'app.
- Risolvere eventuali problemi di installazione e configurazione.
Prerequisiti
Per completare questa esercitazione, è necessario:
- Un account Azure con una sottoscrizione attiva.
- Un PC o Mac che esegue la versione più recente di Visual Studio/Visual Studio Code con il carico di lavoro Sviluppo dell'interfaccia utente app multipiattaforma .NET e i carichi di lavoro di sviluppo ASP.NET e Web installati.
Per Android, è necessario avere:
- Uno sviluppatore ha sbloccato un dispositivo fisico o un emulatore che esegue l'API 26+ con Google Play Services installato.
Per iOS, è necessario avere:
- Un account sviluppatore Apple attivo.
- Un Mac che esegue Xcode, insieme a un certificato dello sviluppatore valido installato nel portachiavi.
Quindi, in iOS è necessario avere:
Simulatore iOS 16+ in esecuzione in macOS 13+ su computer Mac con processori Apple silicon o T2.
OPPURE
Un dispositivo iOS fisico registrato nell'account per sviluppatore (che esegue iOS 13.0+).
Il dispositivo fisico registrato nell'account sviluppatore Apple e associato al certificato.
Importante
Il simulatore iOS supporta le notifiche remote in iOS 16+ durante l'esecuzione in macOS 13+ nei computer Mac con processori Apple silicon o T2. Se non si soddisfano questi requisiti hardware, è necessario un account sviluppatore Apple attivo e un dispositivo fisico.
Per seguire questa esercitazione, è necessario avere familiarità con:
Anche se questa esercitazione è destinata a Visual Studio, è possibile seguirla usando Visual Studio Code in un PC o Mac. Tuttavia, ci saranno alcune differenze che richiedono la riconciliazione. Ad esempio, le descrizioni dell'interfaccia utente e dei flussi di lavoro, i nomi dei modelli e la configurazione dell'ambiente.
Configurare i servizi di notifica push e l'hub di notifica di Azure
In questa sezione verrà configurato Firebase Cloud Messaging e Apple Push Notification Services (APNS). Si creerà e si configurerà quindi un hub di notifica di Azure per l'uso di questi servizi.
Creare un progetto Firebase
Per creare un progetto Firebase:
In un Web browser accedere alla console firebase.
Nella console firebase selezionare il pulsante Aggiungi progetto e creare un nuovo progetto Firebase, immettendo PushDemo come nome progetto.
Nota
Verrà generato automaticamente un nome univoco. Per impostazione predefinita, si tratta di una variante minuscola del nome specificato più un numero generato separato da un trattino. Se lo si desidera, è possibile modificarlo, purché le modifiche siano ancora univoche a livello globale.
Dopo aver creato il progetto, selezionare il logo Android per aggiungere Firebase a un'app Android:
Nella pagina Aggiungi Firebase all'app Android immettere un nome per il pacchetto, facoltativamente un nome alternativo dell'app e selezionare il pulsante Registra app:
Nella pagina Aggiungi Firebase all'app Android selezionare il pulsante Scarica google-services.json e salvare il file in una cartella locale prima di selezionare il pulsante Avanti:
Nella pagina Aggiungi Firebase all'app Android selezionare il pulsante Avanti.
Nella pagina Aggiungi Firebase all'app Android selezionare il pulsante Continua nella console.
Nella console firebase selezionare l'icona Panoramica progetto e quindi selezionare Impostazioni progetto:
Nelle impostazioni del progetto selezionare la scheda Messaggistica cloud. Si noterà che Firebase Cloud Messaging API (V1) è abilitato:
In Impostazioni progetto selezionare la scheda Account di servizio e quindi selezionare il pulsante Genera nuova chiave privata.
Nella finestra di dialogo Genera nuova chiave privata selezionare il pulsante Genera chiave:
Verrà scaricato un file JSON che conterrà i valori immessi nell'hub di notifica di Azure.
Registrare l'app iOS per le notifiche push
Per inviare notifiche push a un'app iOS è necessario registrare l'app con Apple e registrarsi per le notifiche push. A tale scopo, eseguire la procedura descritta nella documentazione di Hub di notifica di Azure seguente:
- Generare il file di richiesta di firma del certificato
- Registrare l'app per le notifiche push
- Creare un certificato per l'hub di notifica
Se vuoi ricevere notifiche push in un dispositivo fisico, dovrai anche creare un profilo di provisioning.
Importante
Per ricevere notifiche in background in iOS, devi aggiungere la modalità in background delle notifiche remote alla tua app. Per altre informazioni, vedere Abilitare la funzionalità di notifiche remote in developer.apple.com.
Creare un hub di notifica di Azure
Per creare un hub di notifica nel portale di Azure:
- In un Web browser accedere al portale di Azure.
- Nella portale di Azure fare clic sul pulsante Crea una risorsa e quindi cercare e scegliere Hub di notifica prima di selezionare il pulsante Crea.
- Nella pagina Hub di notifica seguire questa procedura:
Nel campo Sottoscrizione selezionare il nome della sottoscrizione di Azure che si vuole usare e quindi selezionare un gruppo di risorse esistente o crearne uno nuovo.
Nel campo Dettagli spazio dei nomi immettere un nome univoco per il nuovo spazio dei nomi.
Nel campo Dettagli hub di notifica digitare un nome per l'hub di notifica. Questa operazione è necessaria perché uno spazio dei nomi contiene uno o più hub di notifica.
Nell'elenco a discesa Località selezionare un valore che specifica il percorso in cui si vuole creare l'hub di notifica.
Esaminare l'opzione Zone di disponibilità. Se si sceglie un'area con zone di disponibilità, la casella di controllo è selezionata per impostazione predefinita.
Nota
Le zone di disponibilità sono una funzionalità a pagamento, quindi viene aggiunta una tariffa aggiuntiva al livello.
Scegliere un'opzione di ripristino di emergenza: nessuna, area di ripristino abbinata o area di ripristino flessibile. Se si sceglie Area di ripristino abbinata, viene visualizzata l'area di failover. Se si seleziona Area di ripristino flessibile, usare l'elenco a discesa per scegliere tra un elenco di aree di ripristino.
Selezionare il pulsante Crea. Verrà creato l'hub di notifica.
- Nel portale di Azure passare all'hub di notifica appena creato e quindi al pannello Gestisci criteri > di accesso.
- Nel pannello Criteri di accesso prendere nota del stringa di connessione per il
DefaultFullSharedAccessSignature
criterio. Questa operazione sarà necessaria in un secondo momento quando si compila un servizio back-end che comunica con l'hub di notifica.
Per altre informazioni sulla creazione di un hub di notifica, vedere Creare un hub di notifica di Azure nel portale di Azure.
Configurare Firebase Cloud Messaging nell'hub di notifica
Per configurare l'hub di notifica per comunicare con Firebase Cloud Messaging:
Nel portale di Azure passare all'hub di notifica e selezionare il pannello Impostazioni > Google (FCM v1).
Nel pannello Google (FCM v1) immettere i valori per i campi Chiave privata, Posta elettronica client e ID progetto. Questi valori sono disponibili nel file JSON della chiave privata scaricato da Firebase Cloud Messaging:
Campo di Azure Chiave JSON Esempio di valore JSON Chiave privata private_key
Questo valore deve iniziare con e terminare con -----BEGIN PRIVATE KEY-----\n
-----END PRIVATE KEY-----\n
.Client Email client_email
firebase-adminsdk-55sfg@pushdemo-d6ab2.iam.gserviceaccount.com
ID progetto project_id
pushdemo-d6ab2
Nel pannello Google (FCM v1) selezionare il pulsante Salva .
Configurare Apple Push Notification Service nell'hub di notifica
Nel portale di Azure passare all'hub di notifica e selezionare il pannello Impostazioni > Apple (APNS). Seguire quindi i passaggi appropriati in base all'approccio scelto in precedenza durante la creazione di un certificato per l'hub di notifica.
Importante
Quando si imposta la modalità applicazione, scegliere Produzione solo se si vogliono inviare notifiche push agli utenti che hanno acquistato l'app dallo Store.
Opzione 1- Usare un certificato push p12
- Nel pannello Apple (APNS) selezionare la modalità di autenticazione del certificato .
- Nel pannello Apple (APNS) selezionare l'icona del file accanto al campo Carica certificato . Selezionare quindi il file con estensione p12 esportato in precedenza e caricarlo.
- Nel pannello Apple (APNS) immettere la password del certificato nel campo Password , se necessario.
- Nel pannello Apple (APNS) selezionare la modalità applicazione Sandbox .
- Nel pannello Apple (APNS) selezionare il pulsante Salva .
Opzione 2- Usare l'autenticazione basata su token
- Nel pannello Apple (APNS) selezionare la modalità di autenticazione del token .
- Nel pannello Apple (APNS) immettere i valori acquisiti in precedenza per i campi ID chiave, ID bundle, ID team e Token.
- Nel pannello Apple (APNS) selezionare la modalità applicazione Sandbox .
- Nel pannello Apple (APNS) selezionare il pulsante Salva .
Creare un'app back-end dell'API Web di ASP.NET Core
In questa sezione si creerà un back-end dell'API Web di ASP.NET Core per gestire l'installazione del dispositivo e l'invio di notifiche all'app MAUI .NET.
Creare un progetto di API Web
Per creare un progetto API Web:
In Visual Studio creare un progetto API Web di ASP.NET Core:
Nella finestra di dialogo Configura il nuovo progetto assegnare al progetto il nome PushNotificationsAPI.
Nella finestra di dialogo Informazioni aggiuntive assicurarsi che le caselle di controllo Configura per HTTPS e Usa controller siano abilitate:
Dopo aver creato il progetto, premere F5 per eseguire il progetto.
L'app è attualmente configurata per l'uso
WeatherForecastController
di comelaunchUrl
, impostato nel file Properties\launchSettings.json . L'app verrà avviata in un Web browser e visualizzerà alcuni dati JSON.Importante
Quando si esegue un progetto ASP.NET Core che usa HTTPS, Visual Studio rileverà se il certificato di sviluppo HTTPS di ASP.NET Core è installato nell'archivio certificati utente locale e offrirà di installarlo e considerarlo attendibile se manca.
Chiudere il Web browser.
In Esplora soluzioni espandere la cartella Controller ed eliminare WeatherForecastController.cs.
In Esplora soluzioni, nella radice del progetto, eliminare WeatherForecast.cs.
Aprire una finestra di comando e passare alla directory che contiene il file di progetto. Eseguire quindi i comandi seguenti:
dotnet user-secrets init dotnet user-secrets set "NotificationHub:Name" <value> dotnet user-secrets set "NotificationHub:ConnectionString" "<value>"
Sostituire i valori segnaposto con il nome dell'hub di notifica di Azure e i valori stringa di connessione. Queste informazioni sono disponibili nelle posizioni seguenti nell'hub di notifica di Azure:
Valore di configurazione Ufficio NotificationHub:Name
Vedere Nome nel riepilogo Informazioni di base nella parte superiore della pagina Panoramica . NotificationHub:ConnectinString
Vedere DefaultFullSharedAccessSignature* nella pagina Criteri di accesso. In questo modo vengono impostati i valori di configurazione locali usando lo strumento Secret Manager. In questo modo i segreti dell'hub di notifica di Azure vengono disaccoppiato dalla soluzione Visual Studio per assicurarsi che non finisano nel controllo del codice sorgente.
Suggerimento
Per gli scenari di produzione, prendere in considerazione un servizio come Azure KeyVault per archiviare in modo sicuro il stringa di connessione.
Autenticare i client con una chiave API
Per autenticare i client con una chiave API:
Aprire una finestra di comando e passare alla directory che contiene il file di progetto. Eseguire quindi i comandi seguenti:
dotnet user-secrets set "Authentication:ApiKey" <value>
Sostituire il valore segnaposto con la chiave API, che può essere qualsiasi valore.
In Visual Studio aggiungere una nuova cartella denominata Authentication al progetto e quindi aggiungere una nuova classe denominata
ApiKeyAuthOptions
alla cartella Authentication e sostituirla con il codice seguente: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; } }
In Visual Studio aggiungere una nuova classe denominata
ApiKeyAuthHandler
alla cartella Authentication e sostituirla con il codice seguente: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)); } }
Un gestore di autenticazione è un tipo che implementa il comportamento di uno schema, che in questo caso è uno schema di chiave API personalizzato.
In Visual Studio aggiungere una nuova classe denominata
AuthenticationBuilderExtensions
alla cartella Authentication e sostituirla con il codice seguente: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); } }
Questo metodo di estensione verrà usato per semplificare il codice di configurazione del middleware in Program.cs.
In Visual Studio aprire Program.cs e aggiornare il codice per configurare l'autenticazione della chiave API sotto la chiamata al
builder.Services.AddControllers
metodo :using PushNotificationsAPI.Authentication; builder.Services.AddControllers(); builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = ApiKeyAuthOptions.DefaultScheme; options.DefaultChallengeScheme = ApiKeyAuthOptions.DefaultScheme; }).AddApiKeyAuth(builder.Configuration.GetSection("Authentication").Bind);
In Program.cs aggiornare il codice sotto il
// Configure the HTTP request pipeline
commento per chiamare iUseRouting
metodi di estensione ,UseAuthentication
eMapControllers
:// Configure the HTTP request pipeline. app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
Il
UseAuthentication
metodo di estensione registra il middleware che usa lo schema di autenticazione registrato in precedenza.UseAuthentication
deve essere chiamato prima di qualsiasi middleware che dipende dall'autenticazione degli utenti.Nota
Anche se una chiave API non è sicura come un token, è sufficiente per questa esercitazione e può essere configurata facilmente tramite il middleware ASP.NET.
Aggiungere e configurare i servizi
Per aggiungere e configurare servizi nell'app back-end dell'API Web:
In Visual Studio aggiungere il pacchetto NuGet Microsoft.Azure.NotificationHubs al progetto. Questo pacchetto NuGet viene usato per accedere all'hub di notifica, incapsulato all'interno di un servizio.
In Visual Studio aggiungere una nuova cartella denominata Models al progetto e quindi aggiungere una nuova classe denominata
PushTemplates
alla cartella Models e sostituirla con il codice seguente: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)\" }"; } }
La
PushTemplates
classe contiene payload di notifica con token per le notifiche push generiche e invisibile all'utente. Questi payload vengono definiti all'esterno dell'installazione per consentire la sperimentazione senza dover aggiornare le installazioni esistenti tramite il servizio. La gestione delle modifiche apportate alle installazioni in questo modo non rientra nell'ambito di questo articolo. Negli scenari di prodotto prendere in considerazione l'uso di modelli personalizzati.In Visual Studio aggiungere una nuova classe denominata
DeviceInstallation
alla cartella Models e sostituirla con il codice seguente: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>(); }
In Visual Studio aggiungere una nuova classe denominata
NotificationRequest
alla cartella Models e sostituirla con il codice seguente: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; } }
In Visual Studio aggiungere una nuova classe denominata
NotificationHubOptions
alla cartella Models e sostituirla con il codice seguente:using System.ComponentModel.DataAnnotations; namespace PushNotificationsAPI.Models; public class NotificationHubOptions { [Required] public string Name { get; set; } [Required] public string ConnectionString { get; set; } }
In Visual Studio aggiungere una nuova cartella denominata Services al progetto e quindi aggiungere una nuova interfaccia denominata
INotificationService
alla cartella Services e sostituirla con il codice seguente: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); }
In Visual Studio aggiungere una nuova classe denominata
NotificationHubService
alla cartella Services e sostituirla con il codice seguente: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); } }
L'espressione tag fornita al
SendTemplateNotificationsAsync
metodo è limitata a 20 tag se contengono solo ORS. In caso contrario, sono limitati a 6 tag. Per altre informazioni, vedere Routing ed espressioni tag.In Visual Studio aprire Program.cs e aggiornare il codice per aggiungere come
NotificationHubService
implementazione singleton diINotificationService
sotto la chiamata albuilder.Services.AddAuthentication
metodo :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();
Creare l'API REST per le notifiche
Per creare l'API REST delle notifiche:
In Visual Studio aggiungere un nuovo controller denominato
NotificationsController
alla cartella Controllers .Suggerimento
Scegliere il controller API con il modello di azioni di lettura/scrittura.
Nel file NotificationsController.cs aggiungere le istruzioni seguenti
using
all'inizio del file:using System.ComponentModel.DataAnnotations; using System.Net; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using PushNotificationsAPI.Models; using PushNotificationsAPI.Services;
Nel file NotificationsController.cs aggiungere l'attributo
Authorize
allaNotificationsController
classe :[Authorize] [ApiController] [Route("api/[controller]")] public class NotificationsController : ControllerBase
Nel file NotificationsController.cs aggiornare il
NotificationsContoller
costruttore per accettare l'istanza registrata diINotificationService
come argomento e assegnarlo a un membro readonly:readonly INotificationService _notificationService; public NotificationsController(INotificationService notificationService) { _notificationService = notificationService; }
Nel file NotificationsContoller.cs sostituire tutti i metodi con il codice seguente:
[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(); }
Nel file Proprietà/launchSettings.json modificare la
launchUrl
proprietà per ogni profilo daweatherforecast
aapi/notifications
.
Creare un'app per le API
Si creerà ora un'app per le API in app Azure Servizio per ospitare il servizio back-end. Questa operazione può essere eseguita direttamente da Visual Studio o Visual Studio Code, con l'interfaccia della riga di comando di Azure, Azure PowerShell, l'interfaccia della riga di comando per sviluppatori di Azure e tramite il portale di Azure. Per altre informazioni, vedere Pubblicare l'app Web.
Per creare un'app per le API nel portale di Azure:
In un Web browser accedere al portale di Azure.
Nella portale di Azure fare clic sul pulsante Crea una risorsa e quindi cercare e scegliere App per le API prima di selezionare il pulsante Crea.
Nella pagina Crea app per le API aggiornare i campi seguenti prima di selezionare il pulsante Crea :
Campo Azione Abbonamento Scegliere la stessa sottoscrizione di destinazione in cui è stato creato l'hub di notifica. Gruppo di risorse Scegliere lo stesso gruppo di risorse in cui è stato creato l'hub di notifica. Nome Immettere un nome globalmente univoco. Stack di runtime Assicurarsi che sia selezionata la versione più recente di .NET. Dopo aver effettuato il provisioning dell'app per le API, passare alla risorsa.
Nella pagina Panoramica prendere nota del valore di dominio predefinito. Questo URL è l'endpoint back-end che verrà usato dall'app .NET MAUI. L'URL userà il nome dell'app per le API specificato, con il formato
https://<app_name>.azurewebsites.net
.Nel portale di Azure passare al pannello Impostazioni Variabili > di ambiente e quindi assicurarsi che sia selezionata la scheda Impostazioni app. Usare quindi il pulsante Aggiungi per aggiungere le impostazioni seguenti:
Nome Valore Authentication:ApiKey <api_key_value> NotificationHub:Name <hub_name_value> NotificationHub:ConnectionString <hub_connection_string_value> Importante
L'impostazione
Authentication:ApiKey
dell'applicazione è stata aggiunta per semplicità. Per gli scenari di produzione, prendere in considerazione un servizio come Azure KeyVault per archiviare in modo sicuro il stringa di connessione.Dopo aver immesso tutte queste impostazioni, selezionare il pulsante Applica e quindi il pulsante Conferma .
Pubblicare il servizio back-end
Per pubblicare il servizio back-end nel servizio app Azure:
- In Visual Studio fare clic con il pulsante destro del mouse sul progetto e scegliere Pubblica.
- Nella procedura guidata Pubblica selezionare Azure e quindi il pulsante Avanti.
- Nella procedura guidata Pubblica selezionare app Azure Servizio (Windows) e quindi il pulsante Avanti.
- Nella pubblicazione guidata seguire il flusso di autenticazione per connettere Visual Studio alla sottoscrizione di Azure e pubblicare l'app.
Visual Studio compila, crea pacchetti e pubblica l'app in Azure e quindi avvia l'app nel browser predefinito. Per altre informazioni, vedere Pubblicare un'app Web ASP.NET.
Suggerimento
È possibile scaricare un profilo di pubblicazione per l'app dal pannello Panoramica dell'app per le API nel portale di Azure e quindi usare il profilo in Visual Studio per pubblicare l'app.
Convalidare l'API pubblicata
Per verificare che l'app per le API sia stata pubblicata correttamente, è necessario usare gli strumenti REST di propria scelta per inviare una POST
richiesta all'indirizzo seguente:
https://<app_name>.azurewebsites.net/api/notifications/requests
Nota
L'indirizzo di base è https://<app_name>.azurewebsites.net
.
Assicurarsi di configurare le intestazioni della richiesta per includere la chiave apikey
e il relativo valore, impostare il corpo su raw e usare il contenuto JSON segnaposto seguente:
{}
Si dovrebbe ricevere una 400 Bad Request
risposta dal servizio.
Nota
Non è ancora possibile testare l'API usando dati di richiesta validi, perché saranno necessarie informazioni specifiche della piattaforma dall'app MAUI .NET.
Per altre informazioni sulla chiamata di API REST, vedere Usare file .http in Visual Studio e Testare le API Web con Http Repl. In Visual Studio Code è possibile usare il client REST per testare le API REST.
Creare un'app .NET MAUI
In questa sezione si creerà un'app .NET multipiattaforma dell'interfaccia utente dell'app (.NET MAUI) che consente di eseguire la registrazione per ricevere notifiche push da un hub di notifica tramite il servizio back-end e annullare la registrazione.
Per creare l'app .NET MAUI:
In Visual Studio creare una nuova app MAUI .NET denominata PushNotificationsDemo usando il modello di progetto .NET MAUI App .
In Visual Studio aggiungere una nuova cartella denominata Models al progetto MAUI .NET e quindi aggiungere una nuova classe denominata
DeviceInstallation
alla cartella Models e sostituirla con il codice seguente: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>(); }
In Visual Studio aggiungere un'enumerazione denominata
PushDemoAction
alla cartella Models e sostituirla con il codice seguente:namespace PushNotificationsDemo.Models; public enum PushDemoAction { ActionA, ActionB }
In Visual Studio aggiungere una nuova cartella denominata Services al progetto MAUI .NET e quindi aggiungere una nuova interfaccia denominata
IDeviceInstallationService
alla cartella Services e sostituirla con il codice seguente:using PushNotificationsDemo.Models; namespace PushNotificationsDemo.Services; public interface IDeviceInstallationService { string Token { get; set; } bool NotificationsSupported { get; } string GetDeviceId(); DeviceInstallation GetDeviceInstallation(params string[] tags); }
Questa interfaccia verrà implementata in ogni piattaforma in un secondo momento per fornire le
DeviceInstallation
informazioni richieste dal servizio back-end.In Visual Studio aggiungere un'interfaccia denominata
INotificationRegistrationService
alla cartella Services e sostituirla con il codice seguente:namespace PushNotificationsDemo.Services; public interface INotificationRegistrationService { Task DeregisterDeviceAsync(); Task RegisterDeviceAsync(params string[] tags); Task RefreshRegistrationAsync(); }
Questa interfaccia gestirà l'interazione tra il client e il servizio back-end.
In Visual Studio aggiungere un'interfaccia denominata
INotificationActionService
alla cartella Services e sostituirla con il codice seguente:namespace PushNotificationsDemo.Services; public interface INotificationActionService { void TriggerAction(string action); }
Questa interfaccia verrà usata come meccanismo semplice per centralizzare la gestione delle azioni di notifica.
In Visual Studio aggiungere un'interfaccia denominata
IPushDemoNotificationActionService
alla cartella Services e sostituirla con il codice seguente:using PushNotificationsDemo.Models; namespace PushNotificationsDemo.Services; public interface IPushDemoNotificationActionService : INotificationActionService { event EventHandler<PushDemoAction> ActionTriggered; }
Il
IPushDemoNotificationActionService
tipo è specifico di questa app e usa l'enumerazionePushDemoAction
per identificare l'azione attivata usando un approccio fortemente tipizzato.In Visual Studio aggiungere una classe denominata
NotificationRegistrationService
alla cartella Services e sostituirla con il codice seguente: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(); } }
In Visual Studio aggiungere una classe denominata
PushDemoNotificationActionService
alla cartella Services e sostituirla con il codice seguente: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); } }
In Visual Studio aggiungere una classe denominata
Config
alla radice del progetto e sostituirla con il codice seguente:namespace PushNotificationsDemo; public static partial class Config { public static string ApiKey = "API_KEY"; public static string BackendServiceEndpoint = "BACKEND_SERVICE_ENDPOINT"; }
La
Config
classe viene usata come modo semplice per mantenere i segreti fuori dal controllo del codice sorgente. È possibile sostituire questi valori come parte di una compilazione automatizzata o eseguirne l'override usando una classe parziale locale.Importante
Quando si specifica l'indirizzo di base nell'app MAUI .NET, assicurarsi che termini con .
/
In Visual Studio aggiungere una classe denominata
Config.local_secrets
alla radice del progetto. Sostituire quindi il codice nel file Config.local_secrets.cs con il codice seguente:namespace PushNotificationsDemo; public static partial class Config { static Config() { ApiKey = "<your_api_key>"; BackendServiceEndpoint = "<your_api_app_url>"; } }
Sostituire i valori segnaposto con i valori scelti durante la creazione del servizio back-end. L'URL
BackendServiceEndpoint
deve usare il formatohttps://<api_app_name>.azurewebsites.net/
.Suggerimento
Ricordarsi di aggiungere
*.local_secrets.*
al.gitignore
file per evitare di eseguire il commit di questo file nel controllo del codice sorgente.
Creare l'interfaccia utente
Per creare l'interfaccia utente dell'app:
In Visual Studio aprire MainPage.xaml e sostituire
VerticalStackLayout
e i relativi elementi figlio con il codice XAML seguente:<VerticalStackLayout Margin="20" Spacing="6"> <Button x:Name="registerButton" Text="Register" Clicked="OnRegisterButtonClicked" /> <Button x:Name="deregisterButton" Text="Deregister" Clicked="OnDeregisterButtonClicked" /> </VerticalStackLayout>
In Visual Studio aprire MainPage.xaml.cs e aggiungere un'istruzione
using
per lo spazio deiPushNotificationsDemo.Services
nomi :using PushNotificationsDemo.Services;
In MainPage.xaml.cs aggiungere un
readonly
campo sottostante per archiviare un riferimento all'implementazioneINotificationRegistrationService
:readonly INotificationRegistrationService _notificationRegistrationService;
MainPage
Nel costruttore risolvere l'implementazioneINotificationRegistrationService
e assegnarla al_notificationRegistrationService
campo sottostante:public MainPage(INotificationRegistrationService service) { InitializeComponent(); _notificationRegistrationService = service; }
MainPage
Nella classe implementare iOnRegisterButtonClicked
gestori eventi eOnDeregisterButtonClicked
, chiamando i metodi register e deregister corrispondenti nell'oggettoINotificationRegistrationService
: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; }); }); }
Importante
Nell'app, la registrazione e la de-registrazione vengono eseguite in risposta all'input dell'utente, per consentire l'esplorazione e il test di questa funzionalità più facilmente. In un'app di produzione si eseguiranno in genere le azioni di registrazione e de-registrazione durante il punto appropriato nel ciclo di vita dell'app, senza richiedere l'input esplicito dell'utente.
In Visual Studio aprire App.xaml.cs e aggiungere le istruzioni seguenti
using
:using PushNotificationsDemo.Models; using PushNotificationsDemo.Services;
In App.xaml.cs aggiungere un
readonly
campo sottostante per archiviare un riferimento all'implementazioneIPushDemoNotificationActionService
:readonly IPushDemoNotificationActionService _actionService;
App
Nel costruttore risolvere l'implementazioneIPushDemoNotificationActionService
e assegnarla al_actionService
campo sottostante e sottoscrivere l'eventoIPushDemoNotificationActionService.ActionTriggered
:public App(IPushDemoNotificationActionService service) { InitializeComponent(); _actionService = service; _actionService.ActionTriggered += NotificationActionTriggered; MainPage = new AppShell(); }
App
Nel costruttore risolvere l'implementazioneIPushDemoNotificationActionService
e assegnarla al_actionService
campo sottostante e sottoscrivere l'eventoIPushDemoNotificationActionService.ActionTriggered
:public App(IPushDemoNotificationActionService service) { InitializeComponent(); _actionService = service; _actionService.ActionTriggered += NotificationActionTriggered; }
App
Nella classe implementare il gestore eventi per l'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; }); }); }
Il gestore eventi per l'evento
ActionTriggered
illustra la ricezione e la propagazione delle azioni di notifica push. Questi vengono in genere gestiti automaticamente, ad esempio passando a una visualizzazione specifica o aggiornando alcuni dati anziché visualizzare un avviso.
Configurare l'app Android
Per configurare l'app MAUI .NET in Android per ricevere ed elaborare le notifiche push:
In Visual Studio aggiungere il pacchetto NuGet Xamarin.Firebase.Messaging al progetto di app .NET MAUI.
In Visual Studio aggiungere il file google-services.json alla cartella Platforms/Android del progetto di app .NET MAUI. Dopo aver aggiunto il file al progetto, dovrebbe essere stato aggiunto con un'azione di compilazione di
GoogleServicesJson
:<ItemGroup Condition="'$(TargetFramework)' == 'net8.0-android'"> <GoogleServicesJson Include="Platforms\Android\google-services.json" /> </ItemGroup>
Suggerimento
Ricordarsi di aggiungere
google-services.json
al.gitignore
file per evitare di eseguire il commit di questo file nel controllo del codice sorgente.In Visual Studio modificare il file di progetto (*.csproj) e impostare per Android su
SupportedOSPlatformVersion
26.0:<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">26.0</SupportedOSPlatformVersion>
Google ha apportato modifiche ai canali di notifica Android nell'API 26. Per altre informazioni, vedere Canali di notifica su developer.android.com.
Nella cartella Platforms/Android del progetto aggiungere una nuova classe denominata
DeviceInstallationService
e sostituirla con il codice seguente: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."; } }
Questa classe fornisce un ID univoco, usando il
Secure.AndroidId
valore e il payload di registrazione dell'hub di notifica.Nella cartella Platforms/Android del progetto aggiungere una nuova classe denominata
PushNotificationFirebaseMessagingService
e sostituirla con il codice seguente: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); } }
Questa classe ha un
IntentFilter
attributo che include ilcom.google.firebase.MESSAGING_EVENT
filtro. Questo filtro consente ad Android di passare messaggi in ingresso a questa classe per l'elaborazione.Per informazioni sul formato dei messaggi di Firebase Cloud Messaging, vedere Informazioni sui messaggi FCM in developer.android.com.
In Visual Studio aprire il file MainActivity.cs nella cartella Platforms/Android e aggiungere le istruzioni seguenti
using
:using Android.App; using Android.Content; using Android.Content.PM; using Android.OS; using PushNotificationsDemo.Services; using Firebase.Messaging;
MainActivity
Nella classe impostare suLaunchMode
SingleTop
in modo che l'oggetto non venga nuovamente creato all'aperturaMainActivity
:[Activity( Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
MainActivity
Nella classe aggiungere campi di backup per archiviare i riferimenti alleIPushDemoNotificationActionService
implementazioni eIDeviceInstallationService
:IPushDemoNotificationActionService _notificationActionService; IDeviceInstallationService _deviceInstallationService;
MainActivity
Nella classe aggiungereNotificationActionService
eDeviceInstallationService
private proprietà che recuperano le implementazioni concrete dal contenitore di inserimento delle dipendenze dell'app:IPushDemoNotificationActionService NotificationActionService => _notificationActionService ?? (_notificationActionService = IPlatformApplication.Current.Services.GetService<IPushDemoNotificationActionService>()); IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = IPlatformApplication.Current.Services.GetService<IDeviceInstallationService>());
MainActivity
Nella classe implementare l'interfacciaAndroid.Gms.Tasks.IOnSuccessListener
per recuperare e archiviare il token Firebase:public class MainActivity : MauiAppCompatActivity, Android.Gms.Tasks.IOnSuccessListener { public void OnSuccess(Java.Lang.Object result) { DeviceInstallationService.Token = result.ToString(); } }
MainActivity
Nella classe aggiungere ilProcessNotificationActions
metodo che verificherà se un datoIntent
ha un valore aggiuntivo denominatoaction
e quindi attivare in modo condizionale cheaction
usa l'implementazioneIPushDemoNotificationActionService
: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); } }
Nella classe eseguire l'override
MainActivity
delOnNewIntent
metodo per chiamare ilProcessNotificationActions
metodo :protected override void OnNewIntent(Intent? intent) { base.OnNewIntent(intent); ProcessNotificationsAction(intent); }
Poiché per
LaunchMode
Activity
è impostato suSingleTop
,Intent
un oggetto verrà inviato all'istanza esistenteActivity
tramite l'overrideOnNewIntent
, anziché ilOnCreate
metodo . Pertanto, è necessario gestire una finalità in ingresso sia in cheOnCreate
inOnNewIntent
.Nella classe eseguire l'override
MainActivity
delOnCreate
metodo per chiamare ilProcessNotificationActions
metodo e per recuperare il token da Firebase, aggiungendoMainActivity
comeIOnSuccessListener
:protected override void OnCreate(Bundle? savedInstanceState) { base.OnCreate(savedInstanceState); if (DeviceInstallationService.NotificationsSupported) FirebaseMessaging.Instance.GetToken().AddOnSuccessListener(this); ProcessNotificationsAction(Intent); }
Nota
L'app deve essere nuovamente registrata ogni volta che viene eseguita e arrestarla da una sessione di debug per continuare a ricevere notifiche push.
In Visual Studio aggiungere l'autorizzazione
POST_NOTIFICATIONS
al file AndroidManifest.xml nella cartella Platforms/Android :<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
Per altre informazioni su questa autorizzazione, vedere Autorizzazione runtime di notifica per developer.android.com.
In Visual Studio aprire MainPage.xaml.cs e aggiungere il codice seguente alla
MainPage
classe :#if ANDROID protected override async void OnAppearing() { base.OnAppearing(); PermissionStatus status = await Permissions.RequestAsync<Permissions.PostNotifications>(); } #endif
Questo codice viene eseguito in Android quando
MainPage
viene visualizzato e richiede all'utente di concedere l'autorizzazionePOST_NOTIFICATIONS
. Per altre informazioni sulle autorizzazioni MAUI .NET, vedere Autorizzazioni.
Configurare l'app iOS
Il simulatore iOS supporta le notifiche remote in iOS 16+ durante l'esecuzione in macOS 13+ nei computer Mac con processori Apple silicon o T2. Ogni simulatore genera token di registrazione univoci per la combinazione del simulatore e dell'hardware Mac su cui è in esecuzione.
Importante
Il simulatore supporta l'ambiente sandbox apple Push Notification Service.
Le istruzioni seguenti presuppongono l'uso di hardware che supporta la ricezione di notifiche remote in un simulatore iOS. Se non si tratta del caso, è necessario eseguire l'app iOS in un dispositivo fisico, che richiederà di creare un profilo di provisioning per l'app che include la funzionalità Notifiche push. Sarà quindi necessario assicurarsi che l'app venga compilata usando il certificato e il profilo di provisioning. Per altre informazioni su come eseguire questa operazione, vedere Configurare l'app iOS per l'uso con Hub di notifica di Azure e quindi seguire le istruzioni riportate di seguito.
Per configurare l'app MAUI .NET in iOS per ricevere ed elaborare le notifiche push:
In Visual Studio modificare il file di progetto (*.csproj) e impostare per iOS su
SupportedOSPlatformVersion
13.0:<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">13.0</SupportedOSPlatformVersion>
Apple ha apportato modifiche al servizio push in iOS 13. Per altre informazioni, vedere Aggiornamenti di Hub di notifica di Azure per iOS 13.
In Visual Studio aggiungere un file Entitlements.plist alla cartella Platforms/iOS del progetto e aggiungere il codice XML seguente al file:
<?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>
In questo modo viene impostato l'entitlement dell'ambiente APS e viene specificato l'uso dell'ambiente Apple Push Notification Service per lo sviluppo. Nelle app di produzione questo valore entitlement deve essere impostato su
production
. Per altre informazioni su questo diritto, vedere APS Environment Entitlement on developer.apple.com (Entitlement dell'ambiente APS in developer.apple.com).Per altre informazioni sull'aggiunta di un file entitlement, vedere Entitlement iOS.
In Visual Studio aggiungere una nuova classe denominata
DeviceInstallationService
alla cartella Platforms/iOS del progetto e aggiungere il codice seguente al file: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"; } }
Questa classe fornisce un ID univoco, usando il
UIDevice.IdentifierForVendor
valore e il payload di registrazione dell'hub di notifica.In Visual Studio aggiungere una nuova classe denominata
NSDataExtensions
alla cartella Platforms/iOS del progetto e aggiungere il codice seguente al file: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(); } }
Il
ToHexString
metodo di estensione verrà utilizzato dal codice che verrà aggiunto che analizza il token del dispositivo recuperato.In Visual Studio aprire il file AppDelegate.cs nella cartella Platforms/iOS e aggiungere le istruzioni seguenti
using
:using System.Diagnostics; using Foundation; using PushNotificationsDemo.Platforms.iOS; using PushNotificationsDemo.Services; using UIKit; using UserNotifications;
AppDelegate
Nella classe aggiungere campi di backup per archiviare i riferimenti alleIPushDemoNotificationActionService
implementazioni ,INotificationRegistrationService
eIDeviceInstallationService
:IPushDemoNotificationActionService _notificationActionService; INotificationRegistrationService _notificationRegistrationService; IDeviceInstallationService _deviceInstallationService;
AppDelegate
Nella classe aggiungereNotificationActionService
NotificationRegistrationService
, eDeviceInstallationService
proprietà private che recuperano le implementazioni concrete dal contenitore di inserimento delle dipendenze dell'app: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>());
AppDelegate
Nella classe aggiungere ilCompleteRegistrationAsync
metodo per impostare il valore dellaIDeviceInstallationService.Token
proprietà:Task CompleteRegistrationAsync(NSData deviceToken) { DeviceInstallationService.Token = deviceToken.ToHexString(); return NotificationRegistrationService.RefreshRegistrationAsync(); }
Questo metodo aggiorna anche la registrazione e memorizza nella cache il token del dispositivo se è stato aggiornato dopo l'ultima archiviazione.
AppDelegate
Nella classe aggiungere ilProcessNotificationActions
metodo per elaborare i dati diNSDictionary
notifica e chiamareNotificationActionService.TriggerAction
in modo condizionale :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); } }
AppDelegate
Nella classe aggiungere ilRegisteredForRemoteNotifications
metodo passando l'argomentodeviceToken
alCompleteRegistrationAsync
metodo :[Export("application:didRegisterForRemoteNotificationsWithDeviceToken:")] public void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken) { CompleteRegistrationAsync(deviceToken) .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }); }
Questo metodo verrà chiamato quando l'app viene registrata per ricevere una notifica remota e viene usata per richiedere il token univoco del dispositivo, che è effettivamente l'indirizzo dell'app nel dispositivo.
AppDelegate
Nella classe aggiungere ilReceivedRemoteNotification
metodo passando l'argomentouserInfo
alProcessNotificationActions
metodo :[Export("application:didReceiveRemoteNotification:")] public void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo) { ProcessNotificationActions(userInfo); }
Questo metodo verrà chiamato quando l'app ha ricevuto una notifica remota e viene usata per elaborare la notifica.
AppDelegate
Nella classe aggiungere ilFailedToRegisterForRemoteNotifications
metodo per registrare eventuali errori:[Export("application:didFailToRegisterForRemoteNotificationsWithError:")] public void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error) { Debug.WriteLine(error.Description); }
Questo metodo verrà chiamato quando l'app non è riuscita a registrarsi per ricevere notifiche remote. La registrazione potrebbe non riuscire se il dispositivo non è connesso alla rete, se il server APNS non è raggiungibile o se l'app non è configurata correttamente.
Nota
Per gli scenari di produzione, è necessario implementare la registrazione e la gestione degli errori appropriati nel
FailedToRegisterForRemoteNotifications
metodo .AppDelegate
Nella classe aggiungere il metodo per richiedere in modo condizionale l'autorizzazioneFinishedLaunching
per usare le notifiche e registrarsi per le notifiche remote:[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); }
Per informazioni sulla richiesta dell'autorizzazione per l'uso delle notifiche, vedere La richiesta di autorizzazioni per l'uso delle notifiche in developer.apple.com.
Per informazioni sulle notifiche in iOS, vedere Notifiche utente su developer.apple.com.
Registrare i tipi con il contenitore di inserimento delle dipendenze dell'app
In Visual Studio aprire MauiProgram.cs e aggiungere un'istruzione
using
per lo spazio deiPushNotificationsDemo.Services
nomi :using PushNotificationsDemo.Services;
MauiProgram
Nella classe aggiungere codice per ilRegisterServices
metodo di estensione che registra inDeviceInstallationService
ogni piattaforma e i servizi eNotificationRegistrationService
multipiattaformaPushDemoNotificationActionService
e che restituisce unMauiAppBuilder
oggetto :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; }
MauiProgram
Nella classe aggiungere codice per ilRegisterViews
metodo di estensione che registra ilMainPage
tipo come singleton e che restituisce unMauiAppBuilder
oggetto :public static MauiAppBuilder RegisterViews(this MauiAppBuilder builder) { builder.Services.AddSingleton<MainPage>(); return builder; }
Il
MainPage
tipo viene registrato perché richiede unaINotificationRegistrationService
dipendenza e tutti i tipi che richiedono una dipendenza devono essere registrati con il contenitore di inserimento delle dipendenze.MauiProgram
Nella classe modificare ilCreateMauiApp
metodo in modo che chiami iRegisterServices
metodi di estensione 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(); }
Per altre informazioni sull'inserimento delle dipendenze in .NET MAUI, vedere Inserimento delle dipendenze.
Testare l'app
È possibile testare l'app inviando notifiche push all'app usando il servizio back-end o tramite il portale di Azure.
Il simulatore iOS supporta le notifiche remote in iOS 16+ durante l'esecuzione in macOS 13+ nei computer Mac con processori Apple silicon o T2. Se non si soddisfano questi requisiti hardware, è necessario testare l'app iOS in un dispositivo fisico. In Android è possibile testare l'app in un dispositivo fisico sbloccato dallo sviluppatore o in un emulatore.
Android e iOS visualizzano le notifiche push per conto dell'app quando è in esecuzione in background. Se l'app è in esecuzione in primo piano quando viene ricevuta la notifica, il codice dell'app determina il comportamento. Ad esempio, è possibile aggiornare l'interfaccia dell'app in modo da riflettere le nuove informazioni contenute nella notifica.
Eseguire il test usando il servizio back-end
Per inviare una notifica push di test all'app tramite il servizio back-end pubblicato nel servizio app Azure:
In Visual Studio eseguire l'app PushNotificationsDemo in Android o iOS e selezionare il pulsante Registra .
Nota
Se si esegue il test in Android, assicurarsi di non essere in esecuzione usando la configurazione di debug. In alternativa, se l'app è stata distribuita in precedenza, assicurarsi che sia stata chiusa forzata e quindi avviarla di nuovo dall'utilità di avvio.
Negli strumenti REST di propria scelta inviare una
POST
richiesta all'indirizzo seguente:https://<app_name>.azurewebsites.net/api/notifications/requests
Assicurarsi di configurare le intestazioni della richiesta per includere la chiave
apikey
e il relativo valore, impostare il corpo su raw e usare il contenuto JSON seguente:{ "text": "Message from REST tooling!", "action": "action_a" }
La richiesta complessiva dovrebbe essere simile all'esempio seguente:
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" }
Negli strumenti REST di propria scelta verificare di ricevere una risposta 200 OK .
Nell'app in Android o iOS dovrebbe essere visualizzato un avviso che mostra l'azione ActionA ricevuta.
Per altre informazioni sulla chiamata di API REST, vedere Usare file .http in Visual Studio e Testare le API Web con Http Repl. In Visual Studio Code è possibile usare il client REST per testare le API REST.
Eseguire il test usando il portale di Azure
Hub di notifica di Azure consente di verificare che l'app possa ricevere notifiche push.
Per inviare una notifica push di test all'app tramite il portale di Azure:
In Visual Studio eseguire l'app PushNotificationsDemo in Android o iOS e selezionare il pulsante Registra .
Nota
Se si esegue il test in Android, assicurarsi di non essere in esecuzione usando la configurazione di debug. In alternativa, se l'app è stata distribuita in precedenza, assicurarsi che sia stata chiusa forzata e quindi avviarla di nuovo dall'utilità di avvio.
Nella portale di Azure passare all'hub di notifica e selezionare il pulsante Invia test nel pannello Panoramica.
Nel pannello Invio di test selezionare la piattaforma richiesta e modificare il payload.
Per Apple, usare il payload seguente:
{ "aps": { "alert": "Message from Notification Hub!" }, "action": "action_a" }
Per Android, usare il payload seguente:
{ "message": { "notification": { "title": "PushDemo", "body": "Message from Notification Hub!" }, "data": { "action": "action_a" } } }
Il portale di Azure dovrebbe indicare che la notifica è stata inviata correttamente.
Per informazioni sul formato dei messaggi di Firebase Cloud Messaging, vedere Informazioni sui messaggi FCM in developer.android.com.
Nell'app in Android o iOS dovrebbe essere visualizzato un avviso che mostra l'azione ActionA ricevuta.
Risoluzione dei problemi
Le sezioni seguenti illustrano i problemi comuni riscontrati durante il tentativo di utilizzare le notifiche push in un'app client.
Nessuna risposta dal servizio back-end
Durante i test in locale assicurarsi che il servizio back-end sia in esecuzione e che usi la porta corretta.
Se si esegue il test sull'app per le API di Azure, verificare che il servizio sia in esecuzione e che sia stato distribuito e avviato senza errori.
Assicurarsi di aver specificato correttamente l'indirizzo di base negli strumenti REST o nella configurazione dell'app MAUI .NET. L'indirizzo di base deve essere https://<api_name>.azurewebsites.net
o https://localhost:7020
quando si esegue il test in locale.
Ricezione di un codice di stato 401 dal servizio back-end
Verificare che l'intestazione della apikey
richiesta sia impostata correttamente e che questo valore corrisponda a quello configurato per il servizio back-end.
Se questo errore viene visualizzato durante il test in locale, assicurarsi che il valore della chiave definito nell'app MAUI .NET corrisponda al Authentication:ApiKey
valore dei segreti utente usato dal servizio back-end.
Se si esegue il test con un'app per le API di Azure, assicurarsi che il valore della chiave definito nell'app MAUI .NET corrisponda al Authentication:ApiKey
valore dell'impostazione dell'app definito nella portale di Azure. Se questa impostazione dell'app è stata creata o modificata dopo aver distribuito il servizio back-end, è necessario riavviare il servizio per rendere effettivo il valore.
Ricezione di un codice di stato 404 dal servizio back-end
Verificare che l'endpoint e il metodo di richiesta HTTP siano corretti:
- METTERE-
https://<api_name>.azurewebsites.net/api/notifications/installations
- CANCELLARE-
https://<api_name>.azurewebsites.net/api/notifications/installations/<installation_id>
- INSERISCI-
https://<api_name>.azurewebsites.net/api/notifications/requests
Oppure durante i test in locale:
- METTERE-
https://localhost:7020/api/notifications/installations
- CANCELLARE-
https://localhost:7020/api/notifications/installations/<installation_id>
- INSERISCI-
https://localhost:7020/api/notifications/requests
Importante
Quando si specifica l'indirizzo di base nell'app MAUI .NET, assicurarsi che termini con ./
L'indirizzo di base deve essere https://<api_name>.azurewebsites.net
o https://localhost:7020/
quando si esegue il test in locale.
Mancata ricezione delle notifiche in Android dopo l'avvio o l'arresto di una sessione di debug
Assicurarsi di eseguire la registrazione ogni volta che si avvia una sessione di debug. Il debugger genererà la generazione di un nuovo token Firebase e quindi l'installazione dell'hub di notifica deve essere aggiornata.
Non è possibile eseguire la registrazione e viene visualizzato un messaggio di errore dell'hub di notifica
Verificare che il dispositivo di test abbia connettività di rete. Determinare quindi il codice di stato della risposta HTTP impostando un punto di interruzione per esaminare la StatusCode
proprietà in HttpResponse
.
Esaminare i suggerimenti precedenti per la risoluzione dei problemi, se applicabile, in base al codice di stato.
Impostare un punto di interruzione nelle righe che restituiscono codici di stato specifici per l'API corrispondente. Provare quindi a chiamare il servizio back-end durante il debug in locale.
Verificare che il servizio back-end funzioni come previsto dagli strumenti REST scelti e usare il payload creato dall'app MAUI .NET per la piattaforma scelta.
Esaminare le sezioni di configurazione specifiche della piattaforma per assicurarsi di aver eseguito tutti i passaggi. Verificare che i valori appropriati vengano risolti per InstallationId
le variabili e Token
per la piattaforma scelta.
Impossibile risolvere un ID per il dispositivo nel messaggio di errore del dispositivo
Esaminare le sezioni di configurazione specifiche della piattaforma per assicurarsi di aver eseguito tutti i passaggi.