Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Push-meddelanden levererar information från ett serverdelssystem till en klientapp. Apple, Google och andra plattformar har var och en sin egen push-meddelandetjänst (PNS). Med Azure Notification Hubs kan du centralisera meddelanden mellan plattformar så att din serverdelsapp kan kommunicera med en enda hubb, som tar hand om distribution av meddelanden till varje PNS.
Azure Notification Hubs kräver att appar registrerar sig med hubben och om du vill kan du definiera mallar och/eller prenumerera på taggar:
- När du utför en enhetsinstallation länkas en PNS-referens till en identifierare i Azure Notification Hub. Mer information om registreringar finns i Registreringshantering.
- Med mallar kan enheter ange parameteriserade meddelandemallar. Inkommande meddelanden kan anpassas per enhet. Mer information finns i Notification Hubs-mallar.
- Taggar kan användas för att prenumerera på meddelandekategorier som nyheter, sport och väder. Mer information finns i Routning och tagguttryck.
I den här självstudien använder du Azure Notification Hubs för att skicka push-meddelanden till en .NET Multi-Platform App UI-app (.NET MAUI) som riktar sig till Android och iOS. En ASP.NET Core Web API-serverdel används för att hantera enhetsregistrering för klienten och för att initiera ett push-meddelande. Dessa åtgärder hanteras med hjälp av Microsoft.Azure.NotificationHubs NuGet-paketet. Mer information om den övergripande metoden finns i Registreringshantering från en backend.
I den här handledningen:
- Konfigurera push-meddelandetjänster och Azure Notification Hub.
- Skapa en ASP.NET Core WebAPI-serverdelsapp.
- Skapa en .NET MAUI-app.
- Konfigurera Android-appen för push-meddelanden.
- Konfigurera iOS-appen för push-meddelanden.
- Testa appen.
- Felsöka eventuella konfigurationsproblem.
Förutsättningar
För att slutföra den här självstudien behöver du:
- Ett Azure-konto med en aktiv prenumeration.
- En PC eller Mac som kör den senaste versionen av Visual Studio/Visual Studio Code med arbetsbelastningen för .NET Multi-platform App UI-utveckling och arbetsbelastningarna för ASP.NET och webbapplikationsutveckling installerade.
För Android måste du ha:
- En utvecklare har låst upp en fysisk enhet eller en emulator som kör API 26+ med Google Play Services installerat.
För iOS måste du ha:
- Ett aktivt Apple-utvecklarkonto.
- En Mac som kör Xcode, tillsammans med ett giltigt utvecklarcertifikat installerat i nyckelringen.
Sedan bör du på iOS antingen ha:
- En iOS 16+ simulator som körs i macOS 13+ på Mac-datorer med Apple-kisel- eller T2-processorer. - ELLER 
- En fysisk iOS-enhet som är registrerad på ditt utvecklarkonto (kör iOS 13.0+). 
- Din fysiska enhet som är registrerad på ditt Apple-utvecklarkonto och som är associerad med ditt certifikat. 
Viktig
iOS-simulatorn stöder fjärrmeddelanden i iOS 16+ när den körs i macOS 13+ på Mac-datorer med Apple-kisel- eller T2-processorer. Om du inte uppfyller dessa maskinvarukrav behöver du ett aktivt Apple-utvecklarkonto och en fysisk enhet.
Om du vill följa den här handledningen bör du känna till:
Den här självstudien är avsedd för Visual Studio, men den kan följas med hjälp av Visual Studio Code på en PC eller Mac. Det kommer dock att finnas vissa skillnader som behöver förenas. Till exempel beskrivningar av användargränssnitt och arbetsflöden, mallnamn och miljökonfiguration.
Konfigurera push-meddelandetjänster och Azure Notification Hub
I det här avsnittet konfigurerar du Firebase Cloud Messaging och Apple Push Notification Services (APNS). Sedan skapar och konfigurerar du en Azure Notification Hub- så att den fungerar med dessa tjänster.
Skapa ett Firebase-projekt
Så här skapar du ett Firebase-projekt:
- Logga in på Firebase-konsolen i en webbläsare. 
- I Firebase-konsolen väljer du knappen Lägg till projekt och skapar ett nytt Firebase-projekt och anger PushDemo- som Projektnamn. - Not - Ett unikt namn genereras åt dig. Som standard består detta av en gemen variant av namnet du angav plus ett genererat tal som avgränsas med ett bindestreck. Du kan ändra detta om du vill, förutsatt att dina redigeringar fortfarande är globalt unika. 
- När projektet har skapats väljer du Android-logotypen för att lägga till Firebase i en Android-app:   
- På sidan Lägg till Firebase i din Android-app anger du ett namn för ditt paket, valfritt ett appnamn och väljer knappen Registrera app:   
- På sidan Lägg till Firebase i din Android-app väljer du knappen Ladda ned google-services.json och sparar filen i en lokal mapp innan du väljer knappen Nästa:   
- På sidan Lägg till Firebase i din Android-app väljer du knappen Nästa. 
- På sidan Lägg till Firebase i din Android-app väljer du knappen Fortsätt till konsolen. 
- I Firebase-konsolen väljer du ikonen Projektöversikt och väljer sedan Project-inställningar:   
- I Project-inställningarväljer du fliken Cloud Messaging. Du ser att Firebase Cloud Messaging API (V1) är aktiverat:   
- I Project-inställningarnaväljer du fliken Tjänstkonton och väljer sedan knappen Generera ny privat nyckel. 
- I dialogrutan Generera ny privat nyckel väljer du knappen Generera nyckel:   - En JSON-fil laddas ned, som innehåller värden som du anger i Azure Notification Hub. 
Registrera din iOS-app för push-meddelanden
Om du vill skicka push-meddelanden till en iOS-app måste du registrera din app med Apple och registrera dig för push-meddelanden. Detta kan du göra genom att utföra stegen i följande Dokumentation om Azure Notification Hub:
- Generera begärandefilen för certifikatsignering
- Registrera din app för push-meddelanden
- Skapa ett certifikat för din meddelandehubb
Om du vill ta emot push-meddelanden på en fysisk enhet måste du också skapa en distributionsprofil.
Viktig
Om du vill ta emot bakgrundsmeddelanden i iOS måste du lägga till bakgrundsläget för fjärrmeddelanden i appen. Mer information finns i Aktivera funktionen för fjärrmeddelanden på developer.apple.com.
Skapa en Azure Notification Hub
Så här skapar du en meddelandehubb i Azure-portalen:
- Logga in på Azure-portalen i en webbläsare.
- I Azure-portalen klickar du på knappen Skapa en resurs och söker sedan efter och väljer Notification Hub innan du väljer knappen Skapa.
- Utför följande steg på sidan Notification Hub: - I fältet Prenumeration väljer du namnet på den Azure-prenumeration som du vill använda och väljer sedan en befintlig resursgrupp eller skapar en ny. 
- I fältet Namnområdesinformation anger du ett unikt namn för det nya namnområdet. 
- I fältet Notification Hub Details anger du ett namn för meddelandehubben. Detta krävs eftersom ett namnområde innehåller en eller flera meddelandehubbar. 
- I listrutan Plats väljer du ett värde som anger den plats där du vill skapa meddelandehubben. 
- Granska alternativet tillgänglighetszoner. Om du väljer en region som har tillgänglighetszoner är kryssrutan markerad som standard. - Not - Tillgänglighetszoner är en betald funktion, så en extra avgift läggs till på din nivå. 
- Välj ett katastrofåterställningsalternativ: ingen, parerad återställningsregion eller flexibel återställningsregion. Om du väljer parkopplad återställningsregionvisas failoverregionen. Om du väljer flexibel återställningsregionanvänder du listrutan för att välja från en lista över återställningsregioner. 
- Välj knappen Skapa. Meddelandehubben skapas. 
 
- I Azure-portalen bläddrar du till din nyligen skapade meddelandehubb och sedan till bladet Hantera > åtkomstprinciper.
- Anteckna anslutningssträngen för policyn  i bladet DefaultFullSharedAccessSignature. Du behöver detta senare när du skapar en serverdelstjänst som kommunicerar med din meddelandehubb.
Mer information om hur du skapar en meddelandehubb finns i Skapa en Azure-meddelandehubb i Azure-portalen.
Konfigurera Firebase Cloud Messaging i meddelandehubben
Så här konfigurerar du meddelandehubben så att den kommunicerar med Firebase Cloud Messaging:
- I Azure-portalenbläddrar du till meddelandehubben och väljer bladet Inställningar > Google (FCM v1). 
- På bladet Google (FCM v1) anger du värden för fälten Private Key, Client Emailoch Project ID. Dessa värden finns i JSON-filen med privat nyckel som du laddade ned från Firebase Cloud Messaging: - Azure-fält - JSON-nyckel - JSON-värdeexempel - Privat nyckel - private_key- Det här värdet bör börja med - -----BEGIN PRIVATE KEY-----\noch sluta med- -----END PRIVATE KEY-----\n.- E-post för klient - client_email- firebase-adminsdk-55sfg@pushdemo-d6ab2.iam.gserviceaccount.com- Projekt-ID - project_id- pushdemo-d6ab2
- I bladet Google (FCM v1) väljer du knappen Spara. 
Konfigurera Apple Push Notification Service i meddelandehubben
I Azure-portalenbläddrar du till meddelandehubben och väljer bladet Inställningar > Apple (APNS). Följ sedan lämpliga steg baserat på den metod du valde tidigare när du skapade ett certifikat för meddelandehubben.
Viktig
När du anger programlägeväljer du bara Production om du vill skicka push-meddelanden till användare som har köpt din app från butiken.
Alternativ 1 – Använd ett .p12-pushcertifikat
- På bladet Apple (APNS) väljer du autentiseringsläget Certifikat.
- I bladet Apple (APNS) väljer du fil-ikonen bredvid fältet Ladda upp certifikat. Välj sedan den .p12-fil som du exporterade tidigare och ladda upp den.
- På bladet Apple (APNS) anger du certifikatlösenordet i fältet Lösenord om det behövs.
- På bladet Apple (APNS) väljer du Sandbox- applikationsläge.
- På bladet Apple (APNS) väljer du knappen Spara.
Alternativ 2 – Använda tokenbaserad autentisering
- På bladet Apple (APNS) väljer du Token autentiseringsmetod.
- På bladet Apple (APNS) anger du de värden som du tidigare skaffade för fälten Key ID, Bundle ID, Team IDoch Token.
- På bladet Apple (APNS) väljer du Sandbox- applikationsläge.
- På bladet Apple (APNS) väljer du knappen Spara.
Skapa en ASP.NET Core Web API-serverdelsapp
I det här avsnittet skapar du en ASP.NET Core Web API-serverdel för att hantera enhetsinstallation och skicka meddelanden till .NET MAUI-appen.
Skapa ett webb-API-projekt
Så här skapar du ett webb-API-projekt:
- Skapa ett ASP.NET Core Web API- projekt i Visual Studio:   
- I dialogrutan Konfigurera ditt nya projekt namnger du projektet PushNotificationsAPI. 
- I dialogrutan Ytterligare information kontrollerar du att kryssrutorna Configure for HTTPS and Use controllers är aktiverade:   
- När projektet har skapats trycker du på F5 för att köra projektet. - Appen är för närvarande konfigurerad att använda - WeatherForecastControllersom- launchUrl, som anges i Properties\launchSettings.jspå-filen. Appen startas i en webbläsare och visar vissa JSON-data.- Viktig - När du kör ett ASP.NET Core-projekt som använder HTTPS identifierar Visual Studio om ASP.NET Core HTTPS-utvecklingscertifikatet är installerat i ditt lokala användarcertifikatarkiv och erbjuder att installera det och lita på det om det saknas. 
- Stäng webbläsaren. 
- I Solution Explorerexpanderar du mappen Controllers och tar bort WeatherForecastController.cs. 
- I Solution Exploreri roten av projektet tar du bort WeatherForecast.cs. 
- Öppna ett kommandofönster och navigera till katalogen som innehåller projektfilen. Kör sedan följande kommandon: - dotnet user-secrets init dotnet user-secrets set "NotificationHub:Name" <value> dotnet user-secrets set "NotificationHub:ConnectionString" "<value>"- Ersätt platshållarvärdena med ditt eget Azure Notification Hub-namn och anslutningssträngsvärden. Dessa finns på följande platser i Azure Notification Hub: - Konfigurationsvärde - Plats - NotificationHub:Name- Se Namn i Essentials-sammanfattningen överst på Översikt-sidan . - NotificationHub:ConnectionString- Se DefaultFullSharedAccessSignature* på sidan Åtkomstprinciper. - Detta konfigurerar lokala konfigurationsvärden med hjälp av verktyget Secret Manager. Detta frikopplar dina Azure Notification Hub-hemligheter från Visual Studio-lösningen för att säkerställa att de inte hamnar i källkontrollen. - Tips - För produktionsscenarier bör du överväga en tjänst som Azure KeyVault för att lagra anslutningssträngen på ett säkert sätt. 
Autentisera klienter med en API-nyckel
Så här autentiserar du klienter med en API-nyckel:
- Öppna ett kommandofönster och navigera till katalogen som innehåller projektfilen. Kör sedan följande kommandon: - dotnet user-secrets set "Authentication:ApiKey" <value>- Ersätt platshållarvärdet med din API-nyckel, vilket kan vara valfritt värde. 
- I Visual Studio lägger du till en ny mapp med namnet Authentication i projektet och lägger sedan till en ny klass med namnet - ApiKeyAuthOptionsi mappen Authentication och ersätter koden med följande kod:- 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; } }
- I Visual Studio lägger du till en ny klass med namnet - ApiKeyAuthHandleri mappen Authentication och ersätter koden med följande kod:- 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)); } }- En autentiseringshanterare är en typ som implementerar beteendet för ett schema, vilket i det här fallet är ett anpassat API-nyckelschema. 
- I Visual Studio lägger du till en ny klass med namnet - AuthenticationBuilderExtensionsi mappen Authentication och ersätter koden med följande kod:- 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); } }- Den här tilläggsmetoden används för att förenkla konfigurationskoden för mellanprogram i Program.cs. 
- I Visual Studio öppnar du Program.cs och uppdaterar koden för att konfigurera API-nyckelautentiseringen under anropet till metoden - 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);
- I Program.csuppdaterar du koden under kommentaren - // Configure the HTTP request pipelineför att anropa metoderna- UseRouting,- UseAuthenticationoch- MapControllerstillägg:- // Configure the HTTP request pipeline. app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();- Metoden - UseAuthenticationtillägg registrerar mellanprogrammet som använder det tidigare registrerade autentiseringsschemat.- UseAuthenticationmåste anropas innan mellanprogram som är beroende av att användare autentiseras.- Not - Även om en API-nyckel inte är lika säker som en token, kommer den att räcka för den här självstudien och kan enkelt konfigureras via ASP.NET Middleware. 
Lägga till och konfigurera tjänster
Så här lägger du till och konfigurerar tjänster i din webb-API-serverdelsapp:
- I Visual Studio lägger du till Microsoft.Azure.NotificationHubs NuGet-paketet i projektet. Det här NuGet-paketet används för att komma åt din meddelandehubb, inkapslad i en tjänst. 
- I Visual Studio lägger du till en ny mapp med namnet Models i projektet och lägger sedan till en ny klass med namnet - PushTemplatesi mappen Models och ersätter koden med följande kod:- 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)\" }"; } }- Klassen - PushTemplatesinnehåller tokeniserade meddelandenyttolaster för allmänna och tysta push-meddelanden. Dessa nyttolaster definieras utanför installation för att tillåta experimentering utan att behöva uppdatera befintliga installationer via tjänsten. Att hantera ändringar av installationer på det här sättet ligger utanför omfånget för den här artikeln. I produktscenarier bör du överväga att använda anpassade mallar.
- I Visual Studio lägger du till en ny klass med namnet - DeviceInstallationi mappen Models och ersätter koden med följande kod:- 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>(); }
- I Visual Studio lägger du till en ny klass med namnet - NotificationRequesti mappen Models och ersätter koden med följande kod:- 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; } }
- I Visual Studio lägger du till en ny klass med namnet - NotificationHubOptionsi mappen Models och ersätter koden med följande kod:- using System.ComponentModel.DataAnnotations; namespace PushNotificationsAPI.Models; public class NotificationHubOptions { [Required] public string Name { get; set; } [Required] public string ConnectionString { get; set; } }
- I Visual Studio lägger du till en ny mapp med namnet Services i projektet och lägger sedan till ett nytt gränssnitt med namnet - INotificationServicei mappen Services och ersätter koden med följande kod:- 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); }
- I Visual Studio lägger du till en ny klass med namnet - NotificationHubServicei mappen Services och ersätter koden med följande kod:- 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); } }- Tagguttrycket som tillhandahålls till metoden - SendTemplateNotificationsAsyncär begränsat till 20 taggar om de bara innehåller ORs. Annars är de begränsade till 6 taggar. Mer information finns i Rutthantering och tagguttryck.
- I Visual Studio öppnar du Program.cs och uppdaterar koden för att lägga till - NotificationHubServicesom en singleton-implementering av- INotificationServiceunder anropet till metoden- builder.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();
Skapa REST-API:t för notifikationer
Så här skapar du REST-API:et för meddelanden:
- I Visual Studio lägger du till en ny Controller med namnet - NotificationsControlleri mappen Controllers.- Tips - Välj API-styrenheten med mall för läs-/skrivåtgärder. 
- I filen NotificationsController.cs lägger du till följande - using-instruktioner överst i filen:- using System.ComponentModel.DataAnnotations; using System.Net; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using PushNotificationsAPI.Models; using PushNotificationsAPI.Services;
- I filen NotificationsController.cs lägger du till attributet - Authorizei klassen- NotificationsController:- [Authorize] [ApiController] [Route("api/[controller]")] public class NotificationsController : ControllerBase
- I filen NotificationsController.cs uppdaterar du - NotificationsContollerkonstruktorn för att acceptera den registrerade instansen av- INotificationServicesom ett argument och tilldelar den till en readonly-medlem:- readonly INotificationService _notificationService; public NotificationsController(INotificationService notificationService) { _notificationService = notificationService; }
- I filen NotificationsContoller.cs ersätter du alla metoder med följande kod: - [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(); }
- I filen Egenskaper/launchSettings.json ändrar du egenskapen - launchUrlför varje profil från- weatherforecasttill- api/notifications.
Skapa en API-app
Nu ska du skapa en API-app i Azure App Service- som värd för serverdelstjänsten. Detta kan göras direkt från Visual Studio eller Visual Studio Code, med Azure CLI, Azure PowerShell, Azure Developer CLI och via Azure Portal. Mer information finns i Publicera din webbapp.
Så här skapar du en API-app i Azure-portalen:
- Logga in på Azure-portalen i en webbläsare. 
- I Azure-portalen klickar du på knappen Skapa en resurs och söker sedan efter och väljer API App innan du väljer knappen Skapa. 
- På sidan Skapa API App uppdaterar du följande fält innan du väljer knappen Skapa: - Fält - Handling - Abonnemang - Välj samma målprenumeration som du skapade meddelandehubben i. - Resursgrupp - Välj samma resursgrupp som du skapade meddelandehubben i. - Namn - Ange ett globalt unikt namn. - Körningsstack - Kontrollera att den senaste versionen av .NET är markerad. 
- När API App har etablerats, navigerar du till resursen. 
- Anteckna standarddomänvärdet på sidan Översikt. Den här URL:en är din serverdelsslutpunkt som ska användas från .NET MAUI-appen. URL:en använder det API-appnamn som du angav, med formatet - https://<app_name>.azurewebsites.net.
- I Azure-portalen bläddrar du till bladet Inställningar > Miljö och kontrollerar sedan att fliken Appinställningar är markerad. Använd sedan knappen Lägg till för att lägga till följande inställningar: - Namn - Värde - Autentisering:ApiKey - <api_key_value> - NotificationHub:Name - <hub_name_value> - NotificationHub:ConnectionString - <hub_connection_string_value> - Viktig - Den - Authentication:ApiKeyprograminställningen har lagts till för enkelhetens skull. För produktionsscenarier bör du överväga en tjänst som Azure KeyVault för att lagra anslutningssträngen på ett säkert sätt.- När alla dessa inställningar har angetts väljer du knappen Använd och sedan knappen Bekräfta. 
Publicera serverdelstjänsten
Så här publicerar du serverdelstjänsten till Azure App Service:
- Högerklicka på projektet i Visual Studio och välj Publicera.
- I Publicera-guiden väljer du Azure och trycker sedan på knappen Nästa.
- I guiden Publicera väljer du Azure App Service (Windows) och sedan knappen Nästa.
- I guiden Publicera följer du autentiseringsflödet för att ansluta Visual Studio till din Azure-prenumeration och publicera appen.
Visual Studio skapar, paketerar och publicerar appen till Azure och startar sedan appen i din standardwebbläsare. Mer information finns i Publicera en ASP.NET-webbapp.
Tips
Du kan ladda ned en publiceringsprofil för din app från bladet Översikt api-appen i Azure-portalen och sedan använda profilen i Visual Studio för att publicera din app.
Verifiera det publicerade API:et
Om du vill kontrollera att API-appen har publicerats korrekt bör du använda valfri REST-verktyg för att skicka en POST begäran till följande adress:
https://<app_name>.azurewebsites.net/api/notifications/requests
Not
Basadressen är https://<app_name>.azurewebsites.net.
Se till att du konfigurerar begäranderubrikerna så att de innehåller nyckeln apikey och dess värde, ange brödtexten till rå och använd följande platshållar-JSON-innehåll:
{}
Du bör få ett 400 Bad Request-svar från tjänsten.
Not
Det går ännu inte att testa API:et med giltiga begärandedata eftersom detta kräver plattformsspecifik information från .NET MAUI-appen.
Mer information om hur du anropar REST-API:er finns i Använda .http-filer i Visual Studio och Testa webb-API:er med Http Repl-. I Visual Studio Code kan REST-klient användas för att testa REST-API:er.
Skapa en .NET MAUI-app
I det här avsnittet skapar du en .NET Multi-Platform App UI-app (.NET MAUI) som gör att du kan registrera dig för att ta emot push-meddelanden från en meddelandehubb via serverdelstjänsten och avregistrera dig.
Så här skapar du .NET MAUI-appen:
- I Visual Studio skapar du en ny .NET MAUI-app med namnet PushNotificationsDemomed hjälp av projektmallen .NET MAUI App. 
- I Visual Studio lägger du till en ny mapp med namnet Models i .NET MAUI-projektet och lägger sedan till en ny klass med namnet - DeviceInstallationi mappen Models och ersätter koden med följande kod:- 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>(); }
- I Visual Studio lägger du till en uppräkning med namnet - PushDemoActioni mappen Models och ersätter koden med följande kod:- namespace PushNotificationsDemo.Models; public enum PushDemoAction { ActionA, ActionB }
- I Visual Studio lägger du till en ny mapp med namnet Services till .NET MAUI-projektet och lägger sedan till ett nytt gränssnitt med namnet - IDeviceInstallationServicetill mappen Services och ersätter koden med följande kod:- using PushNotificationsDemo.Models; namespace PushNotificationsDemo.Services; public interface IDeviceInstallationService { string Token { get; set; } bool NotificationsSupported { get; } string GetDeviceId(); DeviceInstallation GetDeviceInstallation(params string[] tags); }- Det här gränssnittet kommer att implementeras på varje plattform vid ett senare tillfälle för att förse den - DeviceInstallation-information som krävs av backendtjänsten.
- I Visual Studio lägger du till ett gränssnitt med namnet - INotificationRegistrationServicei mappen Services och ersätter koden med följande kod:- namespace PushNotificationsDemo.Services; public interface INotificationRegistrationService { Task DeregisterDeviceAsync(); Task RegisterDeviceAsync(params string[] tags); Task RefreshRegistrationAsync(); }- Det här gränssnittet hanterar interaktionen mellan klienten och serverdelstjänsten. 
- I Visual Studio lägger du till ett gränssnitt med namnet - INotificationActionServicei mappen Services och ersätter koden med följande kod:- namespace PushNotificationsDemo.Services; public interface INotificationActionService { void TriggerAction(string action); }- Det här gränssnittet används som en enkel mekanism för att centralisera hanteringen av meddelandeåtgärder. 
- I Visual Studio lägger du till ett gränssnitt med namnet - IPushDemoNotificationActionServicei mappen Services och ersätter koden med följande kod:- using PushNotificationsDemo.Models; namespace PushNotificationsDemo.Services; public interface IPushDemoNotificationActionService : INotificationActionService { event EventHandler<PushDemoAction> ActionTriggered; }- Den - IPushDemoNotificationActionServicetypen är specifik för den här appen och använder- PushDemoActionuppräkning för att identifiera den åtgärd som utlöses med hjälp av en starkt typad metod.
- I Visual Studio lägger du till en klass med namnet - NotificationRegistrationServicei mappen Services och ersätter koden med följande kod:- 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(); } }
- I Visual Studio lägger du till en klass med namnet - PushDemoNotificationActionServicei mappen Services och ersätter koden med följande kod:- 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); } }
- I Visual Studio lägger du till en klass med namnet - Configi projektets rot och ersätter koden med följande kod:- namespace PushNotificationsDemo; public static partial class Config { public static string ApiKey = "API_KEY"; public static string BackendServiceEndpoint = "BACKEND_SERVICE_ENDPOINT"; }- Klassen - Configanvänds som ett enkelt sätt att hålla hemligheterna borta från källkontrollen. Du kan ersätta dessa värden som en del av en automatiserad version eller åsidosätta dem med hjälp av en lokal partiell klass.- Viktig - När du anger basadressen i .NET MAUI-appen ska du se till att den slutar med en - /.
- I Visual Studio lägger du till en klass med namnet - Config.local_secretsi projektets rot. Ersätt sedan koden i filen Config.local_secrets.cs med följande kod:- namespace PushNotificationsDemo; public static partial class Config { static Config() { ApiKey = "<your_api_key>"; BackendServiceEndpoint = "<your_api_app_url>"; } }- Ersätt platshållarvärdena med de värden du valde när du skapade serverdelstjänsten. URL:en för - BackendServiceEndpointska använda formatet- https://<api_app_name>.azurewebsites.net/.- Tips - Kom ihåg att lägga till - *.local_secrets.*i din- .gitignore-fil för att undvika att infoga filen i versionshantering.
Skapa användargränssnittet
Så här skapar du appens användargränssnitt:
- Öppna MainPage.xaml i Visual Studio och ersätt - VerticalStackLayoutoch dess underordnade med följande XAML:- <VerticalStackLayout Margin="20" Spacing="6"> <Button x:Name="registerButton" Text="Register" Clicked="OnRegisterButtonClicked" /> <Button x:Name="deregisterButton" Text="Deregister" Clicked="OnDeregisterButtonClicked" /> </VerticalStackLayout>
- Öppna MainPage.xaml.cs i Visual Studio och lägg till en - using-instruktion för- PushNotificationsDemo.Services-namnområdet:- using PushNotificationsDemo.Services;
- I MainPage.xaml.cslägger du till ett - readonlybakgrundsfält för att lagra en referens till implementeringen av- INotificationRegistrationService:- readonly INotificationRegistrationService _notificationRegistrationService;
- I - MainPagekonstruktorn löser du implementeringen av- INotificationRegistrationServiceoch tilldelar den till- _notificationRegistrationService-bakgrundsfältet:- public MainPage(INotificationRegistrationService service) { InitializeComponent(); _notificationRegistrationService = service; }
- I klassen - MainPageimplementerar du händelsehanterarna- OnRegisterButtonClickedoch- OnDeregisterButtonClickedoch anropar motsvarande register- och avregistermetoder för- INotificationRegistrationService-objektet:- 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; }); }); }- Viktig - I appen utförs registrering och avregistrering som svar på användarindata så att den här funktionen kan utforskas och testas enklare. I en produktionsapp utför du vanligtvis registrerings- och avregistreringsåtgärderna under lämplig punkt i appens livscykel, utan att uttryckligen behöva användarindata. 
- Öppna App.xaml.cs i Visual Studio och lägg till följande - using-instruktioner:- using PushNotificationsDemo.Models; using PushNotificationsDemo.Services;
- I App.xaml.cslägger du till ett - readonly-bakgrundsfält för att lagra en referens till- IPushDemoNotificationActionService-implementeringen:- readonly IPushDemoNotificationActionService _actionService;
- I konstruktor för - Appska du lösa implementeringen av- IPushDemoNotificationActionService, tilldela den till det bakomliggande fältet- _actionServiceoch prenumerera på händelsen- IPushDemoNotificationActionService.ActionTriggered.- public App(IPushDemoNotificationActionService service) { InitializeComponent(); _actionService = service; _actionService.ActionTriggered += NotificationActionTriggered; MainPage = new AppShell(); }
- I konstruktor för - Appska du lösa implementeringen av- IPushDemoNotificationActionService, tilldela den till det bakomliggande fältet- _actionServiceoch prenumerera på händelsen- IPushDemoNotificationActionService.ActionTriggered.- public App(IPushDemoNotificationActionService service) { InitializeComponent(); _actionService = service; _actionService.ActionTriggered += NotificationActionTriggered; }
- I klassen - Appimplementerar du händelsehanteraren för den- IPushDemoNotificationActionService.ActionTriggeredhändelsen:- 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; }); }); }- Händelsehanteraren för den - ActionTriggeredhändelsen visar mottagandet och spridningen av push-meddelandeåtgärder. Dessa skulle vanligtvis hanteras tyst, till exempel navigera till en viss vy eller uppdatera vissa data i stället för att visa en avisering.
Konfigurera Android-appen
Så här konfigurerar du .NET MAUI-appen på Android för att ta emot och bearbeta push-meddelanden:
- I Visual Studio lägger du till Xamarin.Firebase.Messaging- NuGet-paketet i ditt .NET MAUI-appprojekt. 
- I Visual Studio lägger du till din google-services.json-fil i mappen Platforms/Android i ditt .NET MAUI-appprojekt. När filen har lagts till i projektet bör den ha lagts till med en byggåtgärd av - GoogleServicesJson:- <ItemGroup Condition="'$(TargetFramework)' == 'net8.0-android'"> <GoogleServicesJson Include="Platforms\Android\google-services.json" /> </ItemGroup>- Tips - Kom ihåg att lägga till - google-services.jsoni din- .gitignore-fil för att undvika att infoga filen i versionshantering.
- I Visual Studio redigerar du projektfilen (*.csproj) och anger - SupportedOSPlatformVersionför Android till 26.0:- <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">26.0</SupportedOSPlatformVersion>- Google har gjort ändringar i Android-meddelandekanaler i API 26. Mer information finns i Meddelandekanaler på developer.android.com. 
- I mappen Platforms/Android i projektet lägger du till en ny klass med namnet - DeviceInstallationServiceoch ersätter koden med följande kod:- 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."; } }- Den här klassen tilldelar ett unikt ID med värdet - Secure.AndroidIdoch hanterar nyttolasten för registreringen av meddelandehubben.
- I mappen Platforms/Android i projektet lägger du till en ny klass med namnet - PushNotificationFirebaseMessagingServiceoch ersätter koden med följande kod:- 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); } }- Den här klassen har ett - IntentFilterattribut som innehåller- com.google.firebase.MESSAGING_EVENT-filtret. Det här filtret gör att Android kan skicka inkommande meddelanden till den här klassen för bearbetning.- Information om meddelandeformatet Firebase Cloud Messaging finns i Om FCM-meddelanden på developer.android.com. 
- I Visual Studio öppnar du filen MainActivity.cs i mappen Platforms/Android och lägger till följande - using-instruktioner:- using Android.App; using Android.Content; using Android.Content.PM; using Android.OS; using PushNotificationsDemo.Services; using Firebase.Messaging;
- I klassen - MainActivityanger du- LaunchModetill- SingleTopså att- MainActivityinte skapas igen när den öppnas:- [Activity( Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
- I klassen - MainActivitylägger du till bakgrundsfält för att lagra referenser till implementeringarna- IPushDemoNotificationActionServiceoch- IDeviceInstallationService:- IPushDemoNotificationActionService _notificationActionService; IDeviceInstallationService _deviceInstallationService;
- I klassen - MainActivitylägger du till- NotificationActionServiceoch- DeviceInstallationServiceprivata egenskaper som hämtar deras konkreta implementeringar från appens container för beroendeinmatning:- IPushDemoNotificationActionService NotificationActionService => _notificationActionService ?? (_notificationActionService = IPlatformApplication.Current.Services.GetService<IPushDemoNotificationActionService>()); IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = IPlatformApplication.Current.Services.GetService<IDeviceInstallationService>());
- I klassen - MainActivityimplementerar du- Android.Gms.Tasks.IOnSuccessListener-gränssnittet för att hämta och lagra Firebase-token:- public class MainActivity : MauiAppCompatActivity, Android.Gms.Tasks.IOnSuccessListener { public void OnSuccess(Java.Lang.Object result) { DeviceInstallationService.Token = result.ToString(); } }
- I klassen - MainActivitylägger du till metoden- ProcessNotificationActionssom kontrollerar om en viss- Intenthar ett extra värde med namnet- actionoch sedan villkorligt utlöser den- actionmed hjälp av- IPushDemoNotificationActionServiceimplementering:- 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); } }
- I klassen - MainActivityåsidosätter du metoden- OnNewIntentför att anropa metoden- ProcessNotificationActions:- protected override void OnNewIntent(Intent? intent) { base.OnNewIntent(intent); ProcessNotificationsAction(intent); }- Eftersom - LaunchModeför- Activityär inställd på- SingleTopskickas en- Intenttill den befintliga- Activity-instansen via- OnNewIntentöverskridande, snarare än metoden- OnCreate. Därför måste du hantera en inkommande intent i både- OnNewIntentoch- OnCreate.
- I klassen - MainActivityåsidosätter du metoden- OnCreateför att anropa metoden- ProcessNotificationActionsoch för att hämta token från Firebase lägger du till- MainActivitysom- IOnSuccessListener:- protected override void OnCreate(Bundle? savedInstanceState) { base.OnCreate(savedInstanceState); if (DeviceInstallationService.NotificationsSupported) FirebaseMessaging.Instance.GetToken().AddOnSuccessListener(this); ProcessNotificationsAction(Intent); }- Not - Appen måste registreras igen varje gång du kör den och stoppa den från en felsökningssession för att fortsätta ta emot push-meddelanden. 
- I Visual Studio lägger du till behörigheten - POST_NOTIFICATIONSi filen AndroidManifest.xml i mappen Platforms/Android:- <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />- Mer information om den här behörigheten finns i Meddelandekörningsbehörighet på developer.android.com. 
- Öppna MainPage.xaml.cs i Visual Studio och lägg till följande kod i klassen - MainPage:- #if ANDROID protected override async void OnAppearing() { base.OnAppearing(); PermissionStatus status = await Permissions.RequestAsync<Permissions.PostNotifications>(); } #endif- Den här koden körs på Android när - MainPagevisas och begär att användaren beviljar- POST_NOTIFICATIONSbehörighet. Mer information om .NET MAUI-behörigheter finns i Behörigheter.
Konfigurera iOS-appen
iOS-simulatorn stöder fjärrmeddelanden i iOS 16+ när den körs i macOS 13+ på Mac-datorer med Apple-kisel- eller T2-processorer. Varje simulator genererar registreringstoken som är unika för kombinationen av simulatorn och den Mac-maskinvara som den körs på.
Viktig
Simulatorn stöder sandbox-miljön för Apple Push Notification Service.
Följande instruktioner förutsätter att du använder maskinvara som har stöd för att ta emot fjärrmeddelanden i en iOS-simulator. Om så inte är fallet måste du köra iOS-appen på en fysisk enhet, vilket kräver att du skapar en etableringsprofil för din app som innehåller funktionen Push-meddelanden. Sedan måste du se till att din app byggs med hjälp av ditt certifikat och din provisioningprofil. Mer information om hur du gör detta finns i Konfigurera din iOS-app så att den fungerar med Azure Notification Hubsoch följ sedan anvisningarna nedan.
Så här konfigurerar du .NET MAUI-appen på iOS för att ta emot och bearbeta push-meddelanden:
- I Visual Studio redigerar du projektfilen (*.csproj) och anger - SupportedOSPlatformVersionför iOS till 13.0:- <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">13.0</SupportedOSPlatformVersion>- Apple gjorde ändringar i sin push-tjänst i iOS 13. Mer information finns i Azure Notification Hubs-uppdateringar för iOS 13. 
- I Visual Studio lägger du till en Entitlements.plist--fil i mappen Platforms/iOS i projektet och lägger till följande XML i filen: - <?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>- Detta anger berättigande för APS-miljön och anger att du ska använda utvecklingsmiljön för Apple Push Notification Service. I produktionsappar ska det här berättigandevärdet anges till - production. Mer information om den här behörigheten finns i APS-miljörättigheter på developer.apple.com.- Mer information om hur du lägger till en rättighetsfil finns i iOS-berättiganden. 
- I Visual Studio lägger du till en ny klass med namnet - DeviceInstallationServicei mappen Platforms/iOS i projektet och lägger till följande kod i filen:- 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"; } }- Den här klassen tilldelar ett unikt ID med värdet - UIDevice.IdentifierForVendoroch hanterar nyttolasten för registreringen av meddelandehubben.
- I Visual Studio lägger du till en ny klass med namnet - NSDataExtensionsi mappen Platforms/iOS i projektet och lägger till följande kod i filen:- 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(); } }- Utökningsmetoden - ToHexStringkommer att användas av den kod som du lägger till för att parsa den hämtade enhetstoken.
- I Visual Studio öppnar du filen AppDelegate.cs i mappen Platforms/iOS och lägger till följande - using-instruktioner:- using System.Diagnostics; using Foundation; using PushNotificationsDemo.Platforms.iOS; using PushNotificationsDemo.Services; using UIKit; using UserNotifications;
- I klassen - AppDelegatelägger du till bakgrundsfält för att lagra referenser till implementeringarna- IPushDemoNotificationActionService,- INotificationRegistrationServiceoch- IDeviceInstallationService:- IPushDemoNotificationActionService _notificationActionService; INotificationRegistrationService _notificationRegistrationService; IDeviceInstallationService _deviceInstallationService;
- I klassen - AppDelegatelägger du till- NotificationActionService,- NotificationRegistrationServiceoch- DeviceInstallationServiceprivata egenskaper som hämtar sina konkreta implementeringar från appens container för beroendeinmatning:- 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>());
- I klassen - AppDelegatelägger du till metoden- CompleteRegistrationAsyncför att ange egenskapsvärdet- IDeviceInstallationService.Token:- Task CompleteRegistrationAsync(NSData deviceToken) { DeviceInstallationService.Token = deviceToken.ToHexString(); return NotificationRegistrationService.RefreshRegistrationAsync(); }- Den här metoden uppdaterar också registreringen och cachelagrar enhetstoken om den har uppdaterats sedan den senast lagrades. 
- I klassen - AppDelegatelägger du till- ProcessNotificationActions-metoden för bearbetning av- NSDictionary-meddelandedata och anropar villkorligt- NotificationActionService.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); } }
- I klassen - AppDelegatelägger du till metoden- RegisteredForRemoteNotificationssom skickar argumentet- deviceTokentill metoden- CompleteRegistrationAsync:- [Export("application:didRegisterForRemoteNotificationsWithDeviceToken:")] public void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken) { CompleteRegistrationAsync(deviceToken) .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }); }- Den här metoden anropas när appen är registrerad för att ta emot fjärrmeddelanden och används för att begära den unika enhetstoken, som i praktiken är adressen till din app på enheten. 
- I klassen - AppDelegatelägger du till metoden- ReceivedRemoteNotificationsom skickar argumentet- userInfotill metoden- ProcessNotificationActions:- [Export("application:didReceiveRemoteNotification:")] public void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo) { ProcessNotificationActions(userInfo); }- Den här metoden anropas när appen har tagit emot ett fjärrmeddelande och används för att bearbeta meddelandet. 
- I klassen - AppDelegatelägger du till metoden- FailedToRegisterForRemoteNotificationsför att logga eventuella fel:- [Export("application:didFailToRegisterForRemoteNotificationsWithError:")] public void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error) { Debug.WriteLine(error.Description); }- Den här metoden anropas när appen inte har registrerats för att ta emot fjärrmeddelanden. Registreringen kan misslyckas om enheten inte är ansluten till nätverket, om APNS-servern inte kan nås eller om appen är felaktigt konfigurerad. - Not - För produktionsscenarier vill du implementera korrekt loggning och felhantering i metoden - FailedToRegisterForRemoteNotifications.
- I klassen - AppDelegatelägger du till metoden- FinishedLaunchingför att villkorligt begära behörighet att använda meddelanden och registrera dig för fjärrmeddelanden:- [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); }- Information om hur du ber om behörighet att använda meddelanden finns i Fråga om behörighet att använda meddelanden på developer.apple.com. 
Information om meddelanden i iOS finns i användaraviseringar på developer.apple.com.
Registrera typer med appens beroendeinjektionscontainer
- Öppna MauiProgram.cs i Visual Studio och lägg till en - using-instruktion för- PushNotificationsDemo.Services-namnområdet:- using PushNotificationsDemo.Services;
- I klassen - MauiProgramlägger du till kod för- RegisterServices-tilläggsmetoden som registrerar- DeviceInstallationServicepå varje plattform samt plattformsoberoende- PushDemoNotificationActionService- och- NotificationRegistrationService-tjänster och som returnerar ett- MauiAppBuilder-objekt:- 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; }
- I klassen - MauiProgramlägger du till kod för- RegisterViews-tilläggsmetoden som registrerar- MainPagetyp som en singleton och som returnerar ett- MauiAppBuilder-objekt:- public static MauiAppBuilder RegisterViews(this MauiAppBuilder builder) { builder.Services.AddSingleton<MainPage>(); return builder; }- Den - MainPagetypen registreras eftersom den kräver ett- INotificationRegistrationServiceberoende och alla typer som kräver ett beroende måste registreras med containern för beroendeinmatning.
- I klassen - MauiProgramändrar du metoden- CreateMauiAppså att den anropar- RegisterServices- och- RegisterViews-tilläggsmetoderna:- 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(); }
Mer information om beroendeinmatning i .NET MAUI finns i Beroendeinmatning.
Testa appen
Du kan testa din app genom att skicka push-meddelanden till appen med hjälp av serverdelstjänsten eller via Azure-portalen.
iOS-simulatorn stöder fjärrmeddelanden i iOS 16+ när den körs i macOS 13+ på Mac-datorer med Apple-kisel- eller T2-processorer. Om du inte uppfyller dessa maskinvarukrav måste du testa din iOS-app på en fysisk enhet. På Android kan du testa din app på en utvecklarupplåst fysisk enhet eller en emulator.
Android och iOS visar push-meddelanden för appens räkning när den körs i bakgrunden. Om appen körs i förgrunden när meddelandet tas emot avgör appens kod beteendet. Du kan till exempel uppdatera appens gränssnitt så att det återspeglar ny information som finns i meddelandet.
Testa med backend-tjänsten
Så här skickar du ett push-testmeddelande till din app via serverdelstjänsten som publiceras till Azure App Service:
- I Visual Studio kör du appen PushNotificationsDemo på Android eller iOS och väljer knappen Registrera. - Not - Om du testar på Android kontrollerar du att du inte kör med hjälp av felsökningskonfigurationen. Om appen tidigare har distribuerats kan du också se till att den har tvingats stängas och sedan starta den igen från startprogrammet. 
- I valfri REST-verktyg skickar du en - POSTbegäran till följande adress:- https://<app_name>.azurewebsites.net/api/notifications/requests- Se till att du konfigurerar begärandehuvudena så att de innehåller nyckeln - apikeyoch dess värde, ange brödtexten till rå och använd följande JSON-innehåll:- { "text": "Message from REST tooling!", "action": "action_a" }- Den övergripande begäran bör likna följande exempel: - 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" }
- I det REST-verktyg du väljer, kontrollera att du får ett 200 OK svar. 
- I appen på Android eller iOS ska en avisering visas som säger att åtgärden ActionA har tagits emot. 
Mer information om hur du anropar REST-API:er finns i Använda .http-filer i Visual Studio och Testa webb-API:er med Http Repl-. I Visual Studio Code kan REST-klient användas för att testa REST-API:er.
Testa genom hjälp av Azure-portalen
Med Azure Notification Hubs kan du kontrollera att din app kan ta emot push-meddelanden.
Så här skickar du ett push-testmeddelande till din app via Azure-portalen:
- I Visual Studio kör du appen PushNotificationsDemo på Android eller iOS och väljer knappen Registrera. - Not - Om du testar på Android kontrollerar du att du inte kör med hjälp av felsökningskonfigurationen. Om appen tidigare har distribuerats kan du också se till att den har tvingats stängas och sedan starta den igen från startprogrammet. 
- I Azure-portalenbläddrar du till meddelandehubben och väljer knappen Testa skicka på bladet Översikt. 
- I panelen Test Send väljer du din Plattform och ändrar nyttolasten. - För Apple använder du följande nyttolast: - { "aps": { "alert": "Message from Notification Hub!" }, "action": "action_a" }- För Android använder du följande nyttolast: - { "message": { "notification": { "title": "PushDemo", "body": "Message from Notification Hub!" }, "data": { "action": "action_a" } } }- Azure-portalen bör ange att meddelandet har skickats. - Information om meddelandeformatet Firebase Cloud Messaging finns i Om FCM-meddelanden på developer.android.com. 
- I appen på Android eller iOS ska en avisering visas som säger att åtgärden ActionA har tagits emot. 
Felsökning
I följande avsnitt beskrivs de vanliga problem som uppstår vid försök att använda push-meddelanden i en klientapp.
Inget svar från bakgrundstjänsten
När du testar lokalt kontrollerar du att serverdelstjänsten körs och använder rätt port.
Om du testar mot Azure API-appen kontrollerar du att tjänsten körs och har distribuerats och har startats utan fel.
Kontrollera att du har angett basadressen korrekt i REST-verktygen eller i konfigurationen av .NET MAUI-appen. Basadressen ska vara https://<api_name>.azurewebsites.net eller https://localhost:7020 när du testar lokalt.
Ta emot en 401-statuskod från serverdelstjänsten
Kontrollera att du ställer in apikey begärandehuvudet korrekt och att det här värdet matchar det som du har konfigurerat för serverdelstjänsten.
Om du får det här felet när du testar lokalt kontrollerar du att nyckelvärdet som du definierade i .NET MAUI-appen matchar värdet Authentication:ApiKey användarhemligheter som används av serverdelstjänsten.
Om du testar med en Azure API-app kontrollerar du att nyckelvärdet som definierats i .NET MAUI-appen matchar det Authentication:ApiKey appinställningsvärde som definierats i Azure-portalen. Om du har skapat eller ändrat den här appinställningen efter att du har distribuerat serverdelstjänsten måste du starta om tjänsten för att värdet ska börja gälla.
Ta emot en 404-statuskod från serverdelstjänsten
Kontrollera att metoden för slutpunkts- och HTTP-begäran är korrekt:
- PUT - https://<api_name>.azurewebsites.net/api/notifications/installations
- TA BORT – https://<api_name>.azurewebsites.net/api/notifications/installations/<installation_id>
- POST - https://<api_name>.azurewebsites.net/api/notifications/requests
Eller när du testar lokalt:
- PUT - https://localhost:7020/api/notifications/installations
- TA BORT – https://localhost:7020/api/notifications/installations/<installation_id>
- POST- https://localhost:7020/api/notifications/requests
Viktig
När du anger basadressen i .NET MAUI-appen ska du se till att den slutar med en /. Basadressen ska vara https://<api_name>.azurewebsites.net eller https://localhost:7020/ när du testar lokalt.
Får inte meddelanden på Android efter att ha startat eller stoppat en felsökningssession
Kontrollera att du registrerar dig varje gång du startar en felsökningssession. Felsökningsprogrammet gör att en ny Firebase-token genereras och därför måste installationen av meddelandehubben uppdateras.
Det går inte att registrera och felmeddelandet för meddelandehubben visas
Kontrollera att testenheten har nätverksanslutning. Bestäm sedan statuskoden för HTTP-svar genom att ange en brytpunkt för att inspektera egenskapen StatusCode i HttpResponse.
Granska de tidigare felsökningsförslagen, i förekommande fall, baserat på statuskoden.
Ange en brytpunkt på de rader som returnerar specifika statuskoder för respektive API. Försök sedan att anropa serverdelstjänsten när du felsöker lokalt.
Verifiera att serverdelstjänsten fungerar som förväntat med valfritt REST-verktyg och använd den nyttolast som skapats av .NET MAUI-appen för den valda plattformen.
Granska de plattformsspecifika konfigurationsavsnitten för att se till att inga steg har missats. Kontrollera att lämpliga värden löses för InstallationId och Token variabler för den valda plattformen.
Det går inte att identifiera ett ID för enhetsfelmeddelandet.
Granska de plattformsspecifika konfigurationsavsnitten för att se till att inga steg har missats.
 Bläddra bland exempel
               Bläddra bland exempel