Samouczek: wysyłanie powiadomień push do aplikacji .NET MAUI przy użyciu usługi Azure Notification Hubs za pośrednictwem zaplecza.
Powiadomienia push dostarczają informacje z systemu zaplecza do aplikacji klienckiej. Firmy Apple, Google i inne platformy mają własną usługę powiadomień wypychanych (PNS). Usługa Azure Notification Hubs umożliwia scentralizowanie powiadomień na różnych platformach, dzięki czemu aplikacja zaplecza może komunikować się z jednym koncentratorem, który zajmuje się dystrybucją powiadomień do poszczególnych systemów powiadomień.
Usługa Azure Notification Hubs wymaga od aplikacji zarejestrowania się w centrum i opcjonalnie definiowania szablonów i/lub subskrybowania tagów:
- Instalacja urządzenia łączy uchwyt PNS z identyfikatorem w usłudze Azure Notification Hub. Aby uzyskać więcej informacji na temat rejestracji, zobacz Zarządzanie rejestracją.
- Szablony umożliwiają urządzeniom określanie sparametryzowanych szablonów komunikatów. Komunikaty przychodzące można dostosować na urządzenie. Aby uzyskać więcej informacji, zobacz Szablony usługi Notification Hubs.
- Tagi mogą służyć do subskrybowania kategorii wiadomości, takich jak wiadomości, sport i pogoda. Aby uzyskać więcej informacji, zobacz Routing i wyrażenia tagów.
W tym samouczku użyjesz usługi Azure Notification Hubs do wysyłania powiadomień push do wieloplatformowej aplikacji .NET MAUI na systemy Android i iOS. Zaplecze ASP.NET Core Web API służy do obsługi rejestracji urządzeń klienta i inicjowania powiadomień push. Te operacje są obsługiwane przy użyciu pakietu NuGet Microsoft.Azure.NotificationHubs . Aby uzyskać więcej informacji na temat ogólnego podejścia, zobacz Zarządzanie rejestracją z zaplecza.
W tym samouczku ty:
- Konfigurowanie usług powiadomień wypychanych i usługi Azure Notification Hub.
- Utwórz aplikację zaplecza interfejsu WebAPI platformy ASP.NET Core.
- Utwórz aplikację .NET MAUI.
- Skonfiguruj aplikację systemu Android dla powiadomień push.
- Skonfiguruj aplikację iOS dla powiadomień push.
- Testowanie aplikacji.
- Rozwiąż wszelkie problemy z ustawieniami i konfiguracją.
Wymagania wstępne
Do ukończenia tego samouczka wymagane są następujące elementy:
- Konto platformy Azure z aktywną subskrypcją.
- Komputer PC lub Mac z najnowszą wersją programu Visual Studio/Visual Studio Code z obciążeniem tworzenia aplikacji wieloplatformowych platformy .NET oraz zainstalowanymi obciążeniami tworzenia aplikacji ASP.NET i aplikacji internetowych.
W przypadku systemu Android musisz mieć następujące elementy:
- Odblokowane przez programistę urządzenie fizyczne lub emulator z zainstalowanym API 26 lub nowszym oraz usługami Google Play.
W przypadku systemu iOS musisz mieć następujące elementy:
- Aktywne konto dewelopera firmy Apple.
- Komputer Mac z zainstalowanym Xcode oraz ważnym certyfikatem dewelopera zainstalowanym w Keychain.
Następnie w systemie iOS powinieneś mieć:
Symulator systemu iOS 16+ działający w systemie macOS 13 lub nowszym na komputerach Mac z procesorami krzemowymi firmy Apple lub T2.
LUB
Fizyczne urządzenie z systemem iOS zarejestrowane na koncie dewelopera (z systemem iOS 13.0 lub nowszym).
Urządzenie fizyczne zarejestrowane na koncie dewelopera firmy Apple i skojarzone z certyfikatem.
Ważne
Symulator systemu iOS obsługuje powiadomienia zdalne w systemie iOS 16 lub nowszym podczas uruchamiania w systemie macOS 13 lub nowszym na komputerach Mac z procesorami krzemowymi firmy Apple lub T2. Jeśli nie spełniasz tych wymagań sprzętowych, musisz mieć aktywne konto dewelopera firmy Apple i urządzenie fizyczne.
Aby wykonać czynności opisane w tym samouczku, musisz zapoznać się z następującymi tematami:
- Portal dla deweloperów firmy Apple
- ASP.NET Core i internetowe interfejsy API
- Firebase Cloud Messaging
- Microsoft Azure
Chociaż ten samouczek jest przeznaczony dla programu Visual Studio, można go wykonać przy użyciu programu Visual Studio Code na komputerze PC lub Mac. Jednak będą istnieć pewne różnice, które wymagają uzgadniania. Na przykład opisy interfejsu użytkownika i przepływów pracy, nazw szablonów i konfiguracji środowiska.
Konfigurowanie usług powiadomień wypychanych i usługi Azure Notification Hub
W tej sekcji skonfigurujesz usługę Firebase Cloud Messaging i Apple Push Notification Services (APNS). Następnie utworzysz i skonfigurujesz usługę Azure Notification Hub do pracy z tymi usługami.
Tworzenie projektu Firebase
Aby utworzyć projekt Firebase:
W przeglądarce internetowej zaloguj się do konsoli Firebase.
W konsoli Firebase wybierz przycisk Dodaj projekt i utwórz nowy projekt Firebase, wprowadzając wartość PushDemo jako nazwę projektu.
Uwaga
Zostanie wygenerowana unikatowa nazwa. Domyślnie składa się z małego wariantu podanej nazwy oraz wygenerowanej liczby rozdzielonej kreską. Możesz to zmienić, jeśli chcesz, pod warunkiem, że zmiany są nadal unikatowe globalnie.
Po utworzeniu projektu wybierz logo systemu Android, aby dodać aplikację Firebase do aplikacji systemu Android:
Na stronie Dodawanie aplikacji Firebase do aplikacji systemu Android wprowadź nazwę pakietu, opcjonalnie pseudonim aplikacji i wybierz przycisk Zarejestruj aplikację :
Na stronie Dodawanie programu Firebase do aplikacji systemu Android wybierz przycisk Pobierz google-services.json i zapisz plik w folderze lokalnym przed wybraniem przycisku Dalej :
Na stronie Dodawanie aplikacji Firebase do aplikacji systemu Android wybierz przycisk Dalej.
Na stronie Dodawanie bazy danych Firebase do aplikacji systemu Android wybierz przycisk Kontynuuj w konsoli.
W konsoli Firebase wybierz ikonę Przegląd projektu, a następnie wybierz pozycję Ustawienia projektu:
W ustawieniach projektu wybierz kartę Cloud Messaging (Obsługa komunikatów w chmurze). Zobaczysz, że interfejs API usługi Firebase Cloud Messaging (V1) jest włączony:
W ustawieniach projektu wybierz kartę Konta usług, a następnie wybierz przycisk Generuj nowy klucz prywatny.
W oknie dialogowym Generowanie nowego klucza prywatnego wybierz przycisk Generuj klucz:
Zostanie pobrany plik JSON, który będzie zawierać wartości wprowadzone w usłudze Azure Notification Hub.
Zarejestruj swoją aplikację iOS do powiadomień push
Aby wysyłać powiadomienia push do aplikacji na iOS, musisz zarejestrować aplikację u Apple i zarejestrować do powiadomień push. Można to zrobić, wykonując kroki opisane w następującej dokumentacji usługi Azure Notification Hub:
- Generowanie pliku żądania podpisania certyfikatu
- Zarejestruj swoją aplikację dla powiadomień push
- Tworzenie certyfikatu dla centrum powiadomień
Jeśli chcesz otrzymywać powiadomienia push na urządzeniu fizycznym, musisz również utworzyć profil prowizyjny.
Ważne
Aby otrzymywać powiadomienia w tle w systemie iOS, musisz dodać tryb tła powiadomień zdalnych do aplikacji. Aby uzyskać więcej informacji, zobacz Włączanie możliwości powiadomień zdalnych w developer.apple.com.
Tworzenie centrum powiadomień platformy Azure
Aby utworzyć centrum powiadomień w witrynie Azure Portal:
- W przeglądarce internetowej zaloguj się do witryny Azure Portal.
- W witrynie Azure Portal kliknij przycisk Utwórz zasób , a następnie wyszukaj i wybierz pozycję Centrum powiadomień przed wybraniem przycisku Utwórz .
-
Na stronie Centrum powiadomień wykonaj następujące kroki:
W polu Subskrypcja wybierz nazwę subskrypcji platformy Azure, której chcesz użyć, a następnie wybierz istniejącą grupę zasobów lub utwórz nową.
W polu Szczegóły przestrzeni nazw wprowadź unikatową nazwę nowej przestrzeni nazw.
W polu Szczegóły centrum powiadomień wpisz nazwę centrum powiadomień. Jest to wymagane, ponieważ przestrzeń nazw zawiera co najmniej jedno centrum powiadomień.
Z listy rozwijanej Lokalizacja wybierz wartość określającą lokalizację, w której chcesz utworzyć centrum powiadomień.
Przejrzyj opcję Strefy dostępności. Jeśli wybrano region ze strefami dostępności, pole wyboru jest zaznaczone domyślnie.
Uwaga
Strefy dostępności to funkcja płatna, więc dodatkowa opłata jest naliczana do twojego planu.
Wybierz opcję Odzyskiwania po awarii: brak, sparowany region odzyskiwania lub elastyczny region odzyskiwania. Jeśli wybierzesz sparowany region odzyskiwania, zostanie wyświetlony region awaryjny. Jeśli wybierzesz pozycję Elastyczny region odzyskiwania, użyj listy rozwijanej, aby wybrać z listy regionów odzyskiwania.
Zaznacz przycisk Utwórz. Zostanie utworzone centrum powiadomień.
- W portalu Azure przejdź do nowo utworzonego centrum powiadomień, a następnie do sekcji
Zarządzanie zasadami dostępu . - W bloku Polityki dostępu zanotuj ciąg połączenia dla polityki
DefaultFullSharedAccessSignature
. Będzie to wymagane później podczas tworzenia usługi zaplecza, która komunikuje się z centrum powiadomień.
Aby uzyskać więcej informacji na temat tworzenia centrum powiadomień, zobacz Tworzenie centrum powiadomień platformy Azure w witrynie Azure Portal.
Konfigurowanie usługi Firebase Cloud Messaging w centrum powiadomień
Aby skonfigurować centrum powiadomień do komunikowania się z usługą Firebase Cloud Messaging:
W portalu Azure przejdź do swojego centrum powiadomień i wybierz panel Ustawienia > Google (FCM v1).
W panelu Google (FCM v1) wprowadź wartości dla pól Prywatny klucz, Adres e-mail klienta oraz ID projektu. Te wartości można znaleźć w pliku JSON klucza prywatnego pobranym z usługi Firebase Cloud Messaging:
Pole Azure Klucz JSON Przykład wartości JSON Klucz prywatny private_key
Ta wartość powinna zaczynać się od -----BEGIN PRIVATE KEY-----\n
i kończyć ciągiem-----END PRIVATE KEY-----\n
.Adres e-mail klienta client_email
firebase-adminsdk-55sfg@pushdemo-d6ab2.iam.gserviceaccount.com
Identyfikator projektu project_id
pushdemo-d6ab2
W panelu Google (FCM v1) wybierz przycisk Zapisz.
Konfigurowanie usługi Apple Push Notification Service w centrum powiadomień
W witrynie Azure portal przejdź do swojego centrum powiadomień i wybierz panel Ustawienia > Apple (APNS). Następnie wykonaj odpowiednie kroki na podstawie podejścia wybranego wcześniej podczas tworzenia certyfikatu dla centrum powiadomień.
Ważne
Podczas ustawiania trybu aplikacji wybierz pozycję Produkcja tylko wtedy, gdy chcesz wysyłać powiadomienia wypychane do użytkowników, którzy kupili aplikację ze sklepu.
Opcja 1 — używanie certyfikatu push .p12
- W bloku Apple (APNS) wybierz tryb uwierzytelniania certyfikatu.
- W bloku Apple (APNS) wybierz ikonę pliku obok pola Przekaż certyfikat. Następnie wybierz wyeksportowany wcześniej plik .p12 i prześlij go.
- W bloku Apple (APNS) wprowadź hasło certyfikatu w polu Hasło, jeśli jest to wymagane.
- W bloku Apple (APNS) wybierz tryb aplikacji piaskownicy.
- W panelu Apple (APNS) wybierz przycisk Zapisz.
Opcja 2 — używanie uwierzytelniania opartego na tokenach
- W bloku Apple (APNS) wybierz tryb uwierzytelniania tokenu.
- W bloku Apple (APNS) wprowadź wcześniej zdobyte wartości dla pól Identyfikator klucza, Identyfikator pakietu, Identyfikator zespołu i Token.
- W panelu Apple (APNS) wybierz tryb aplikacji Sandbox.
- W bloku Apple (APNS) wybierz przycisk Zapisz.
Utwórz aplikację back-endową Web API platformy ASP.NET Core
W tej sekcji utworzysz zaplecze internetowego interfejsu API platformy ASP.NET Core do obsługi instalacji urządzenia i wysyłania powiadomień do aplikacji .NET MAUI.
Tworzenie projektu internetowego interfejsu API
Aby utworzyć projekt internetowego interfejsu API:
W programie Visual Studio utwórz projekt internetowego interfejsu API platformy ASP.NET Core:
W oknie dialogowym Konfigurowanie nowego projektu nadaj projektowi nazwę PushNotificationsAPI.
W oknie dialogowym Dodatkowe informacje upewnij się, że pole wyboru Konfiguruj dla protokołu HTTPS i Użyj kontrolerów jest włączone:
Po utworzeniu projektu naciśnij F5 , aby uruchomić projekt.
Aplikacja jest obecnie skonfigurowana do używania
WeatherForecastController
jakolaunchUrl
, co jest ustawione w pliku Properties\launchSettings.json. Aplikacja zostanie uruchomiona w przeglądarce internetowej i wyświetli niektóre dane JSON.Ważne
Po uruchomieniu projektu ASP.NET Core korzystającego z protokołu HTTPS program Visual Studio wykryje, czy certyfikat dewelopera ASP.NET Core HTTPS jest zainstalowany w magazynie certyfikatów użytkownika lokalnego i będzie oferować jego zainstalowanie i zaufanie, jeśli go brakuje.
Zamknij przeglądarkę internetową.
W Eksplorator rozwiązań rozwiń folder Controllers i usuń WeatherForecastController.cs.
W Eksplorator rozwiązań w katalogu głównym projektu usuń WeatherForecast.cs.
Otwórz okno polecenia i przejdź do katalogu zawierającego plik projektu. Użyj następujących poleceń:
dotnet user-secrets init dotnet user-secrets set "NotificationHub:Name" <value> dotnet user-secrets set "NotificationHub:ConnectionString" "<value>"
Zastąp wartości symboli zastępczych własną nazwą usługi Azure Notification Hub i wartościami parametrów połączenia. Można je znaleźć w następujących lokalizacjach w usłudze Azure Notification Hub:
Wartość konfiguracji Lokalizacja NotificationHub:Name
Zobacz Nazwę w Podsumowaniu Essentials na górze strony Przegląd. NotificationHub:ConnectionString
Zobacz DefaultFullSharedAccessSignature* na stronie Zasady Dostępu. Spowoduje to skonfigurowanie lokalnych wartości konfiguracji przy użyciu narzędzia Secret Manager. Spowoduje to odseparowanie tajnych danych usługi Azure Notification Hub od rozwiązania Visual Studio, aby mieć pewność, że nie trafiły do systemu kontroli wersji.
Napiwek
W przypadku scenariuszy produkcyjnych rozważ usługę, taką jak Azure KeyVault, aby bezpiecznie przechowywać parametry połączenia.
Uwierzytelnianie klientów przy użyciu klucza interfejsu API
Aby uwierzytelnić klientów przy użyciu klucza interfejsu API:
Otwórz okno polecenia i przejdź do katalogu zawierającego plik projektu. Użyj następujących poleceń:
dotnet user-secrets set "Authentication:ApiKey" <value>
Zastąp wartość symbolu zastępczego kluczem interfejsu API, który może przyjąć dowolną wartość.
W programie Visual Studio dodaj nowy folder o nazwie Authentication do projektu, a następnie dodaj nową klasę o nazwie do
ApiKeyAuthOptions
i zastąp jego kod następującym kodem: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; } }
W programie Visual Studio dodaj nową klasę o nazwie
ApiKeyAuthHandler
do folderu Authentication i zastąp jego kod następującym kodem: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)); } }
Procedura obsługi uwierzytelniania to typ implementujący zachowanie schematu, który w tym przypadku jest niestandardowym schematem kluczy interfejsu API.
W programie Visual Studio dodaj nową klasę o nazwie
AuthenticationBuilderExtensions
do folderu Authentication i zastąp jego kod następującym kodem: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); } }
Ta metoda rozszerzenia zostanie użyta do uproszczenia kodu konfiguracji oprogramowania pośredniczącego w Program.cs.
W programie Visual Studio otwórz Program.cs i zaktualizuj kod, aby skonfigurować uwierzytelnianie klucza interfejsu API poniżej wywołania
builder.Services.AddControllers
metody :using PushNotificationsAPI.Authentication; builder.Services.AddControllers(); builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = ApiKeyAuthOptions.DefaultScheme; options.DefaultChallengeScheme = ApiKeyAuthOptions.DefaultScheme; }).AddApiKeyAuth(builder.Configuration.GetSection("Authentication").Bind);
W Program.cs zaktualizuj kod poniżej komentarza
// Configure the HTTP request pipeline
, aby wywołać metody rozszerzeń:UseRouting
,UseAuthentication
iMapControllers
.// Configure the HTTP request pipeline. app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
Metoda
UseAuthentication
rozszerzenia rejestruje oprogramowanie pośredniczące, które używa wcześniej zarejestrowanego schematu uwierzytelniania.UseAuthentication
należy wywołać przed każdym oprogramowaniem pośredniczącym, które zależy od uwierzytelnienia użytkowników.Uwaga
Chociaż klucz API nie jest tak bezpieczny jak token, wystarczy na potrzeby tego samouczka i będzie można go łatwo skonfigurować za pomocą ASP.NET Middleware.
Dodawanie i konfigurowanie usług
Aby dodać i skonfigurować usługi w aplikacji backendu interfejsu API sieci:
W programie Visual Studio dodaj pakiet NuGet Microsoft.Azure.NotificationHubs do projektu. Ten pakiet NuGet służy do uzyskiwania dostępu do centrum powiadomień, osadzonego w usłudze.
W programie Visual Studio dodaj nowy folder o nazwie Models do projektu, a następnie dodaj nową klasę o nazwie
PushTemplates
do folderu Models i zastąp jego kod następującym kodem: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)\" }"; } }
Klasa
PushTemplates
zawiera tokenizowane ładunki powiadomień dla ogólnych i cichych powiadomień wypychanych. Te ładunki są definiowane poza instalacją, aby umożliwić eksperymentowanie bez konieczności aktualizowania istniejących instalacji za pośrednictwem usługi. Obsługa zmian w instalacjach w ten sposób jest poza zakresem tego artykułu. W scenariuszach produktów rozważ użycie szablonów niestandardowych.W programie Visual Studio dodaj nową klasę o nazwie
DeviceInstallation
do folderu Models i zastąp kod następującym kodem: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>(); }
W programie Visual Studio dodaj nową klasę o nazwie
NotificationRequest
do folderu Models i zastąp kod następującym kodem: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; } }
W programie Visual Studio dodaj nową klasę o nazwie
NotificationHubOptions
do folderu Models i zastąp kod następującym kodem:using System.ComponentModel.DataAnnotations; namespace PushNotificationsAPI.Models; public class NotificationHubOptions { [Required] public string Name { get; set; } [Required] public string ConnectionString { get; set; } }
W programie Visual Studio dodaj nowy folder o nazwie Services do projektu, a następnie dodaj nowy interfejs o nazwie
INotificationService
do folderu Services i zastąp jego kod następującym kodem: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); }
W programie Visual Studio dodaj nową klasę o nazwie
NotificationHubService
do folderu Services i zastąp jego kod następującym kodem: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); } }
Wyrażenie tagów dostarczone do metody
SendTemplateNotificationsAsync
jest ograniczone do 20 tagów, jeśli zawiera tylko operatory OR. W przeciwnym razie są one ograniczone do 6 tagów. Aby uzyskać więcej informacji, zobacz Routing i wyrażenia tagów.W programie Visual Studio otwórz Program.cs i zaktualizuj kod, aby dodać
NotificationHubService
jako implementację singletonuINotificationService
, poniżej wywołania metodybuilder.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();
Tworzenie interfejsu API REST powiadomień
Aby utworzyć interfejs API REST powiadomień:
W programie Visual Studio dodaj nowy kontroler o nazwie
NotificationsController
do folderu Controllers .Napiwek
Wybierz szablon Kontrolera API z akcjami odczytu i zapisu.
W pliku NotificationsController.cs dodaj następujące
using
instrukcje w górnej części pliku:using System.ComponentModel.DataAnnotations; using System.Net; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using PushNotificationsAPI.Models; using PushNotificationsAPI.Services;
W pliku NotificationsController.cs dodaj
Authorize
atrybut doNotificationsController
klasy:[Authorize] [ApiController] [Route("api/[controller]")] public class NotificationsController : ControllerBase
W pliku NotificationsController.cs zaktualizuj konstruktor
NotificationsContoller
, aby przyjmował jako argument zarejestrowane wystąpienieINotificationService
i przypisz je do pola tylko do odczytu.readonly INotificationService _notificationService; public NotificationsController(INotificationService notificationService) { _notificationService = notificationService; }
W pliku NotificationsContoller.cs zastąp wszystkie metody następującym kodem:
[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(); }
W pliku Właściwości/launchSettings.json zmień
launchUrl
właściwość dla każdego profilu zweatherforecast
naapi/notifications
.
Utwórz aplikację API
Teraz utworzysz aplikację interfejsu API w usłudze Azure App Service, aby hostować usługę zaplecza. Można to zrobić bezpośrednio z poziomu programu Visual Studio lub Visual Studio Code przy użyciu interfejsu wiersza polecenia platformy Azure, programu Azure PowerShell, interfejsu wiersza polecenia dla deweloperów platformy Azure i witryny Azure Portal. Aby uzyskać więcej informacji, zobacz Publikowanie aplikacji internetowej.
Aby utworzyć aplikację API w Azure Portal:
W przeglądarce internetowej zaloguj się do witryny Azure Portal.
W portalu Azure kliknij przycisk Utwórz zasób, a następnie wyszukaj i wybierz Aplikację API przed kliknięciem przycisku Utwórz.
Na stronie Tworzenie aplikacji interfejsu API zaktualizuj następujące pola przed wybraniem przycisku Utwórz:
Pole Akcja Subskrypcja Wybierz tę samą subskrypcję docelową, w której utworzono centrum powiadomień. Grupa zasobów Wybierz tę samą grupę zasobów, w której utworzono centrum powiadomień. Nazwisko Podaj globalnie unikatową nazwę. Stos środowiska uruchomieniowego Upewnij się, że wybrano najnowszą wersję platformy .NET. Po aprowizacji aplikacji API przejdź do zasobu.
Na stronie Przegląd zanotuj domyślną wartość domeny. Ten URL to punkt końcowy zaplecza, który będzie wykorzystywany przez aplikację .NET MAUI. Adres URL będzie używać nazwy aplikacji API, którą określiłeś, w formacie
https://<app_name>.azurewebsites.net
.W witrynie Azure Portal przejdź do bloku Ustawienia > Zmienne środowiskowe , a następnie upewnij się, że wybrano kartę Ustawienia aplikacji. Następnie użyj przycisku Dodaj , aby dodać następujące ustawienia:
Nazwisko Wartość Authentication:ApiKey <api_key_value> NotificationHub:Name <hub_name_value> NotificationHub:ConnectionString <hub_connection_string_value> Ważne
Dodano ustawienie aplikacji
Authentication:ApiKey
dla uproszczenia. W przypadku scenariuszy produkcyjnych rozważ usługę, taką jak Azure KeyVault, aby bezpiecznie przechowywać parametry połączenia.Po wprowadzeniu wszystkich tych ustawień wybierz przycisk Zastosuj , a następnie przycisk Potwierdź .
Publikowanie usługi zaplecza
Aby opublikować swoją usługę zaplecza w usłudze Azure App Service:
- W programie Visual Studio kliknij prawym przyciskiem myszy projekt i wybierz polecenie Publikuj.
- W kreatorze Publikowanie wybierz pozycję Azure, a następnie przycisk Dalej.
- W kreatorze Publikuj wybierz pozycję Azure App Service (Windows), a następnie przycisk Dalej.
- W kreatorze Publikowanie postępuj zgodnie z przepływem uwierzytelniania, aby połączyć program Visual Studio z subskrypcją platformy Azure i opublikować aplikację.
Program Visual Studio kompiluje, pakuje i publikuje aplikację na platformie Azure, a następnie uruchamia aplikację w domyślnej przeglądarce. Aby uzyskać więcej informacji, zobacz Publikowanie ASP.NET aplikacji internetowej.
Napiwek
Profil publikowania dla aplikacji API można pobrać z karty Przegląd w portalu Azure, a następnie użyć tego profilu w programie Visual Studio do opublikowania aplikacji.
Weryfikowanie opublikowanego interfejsu API
Aby sprawdzić, czy aplikacja interfejsu API została poprawnie opublikowana, należy użyć wybranego narzędzia REST, aby wysłać POST
żądanie do następującego adresu:
https://<app_name>.azurewebsites.net/api/notifications/requests
Uwaga
Adres podstawowy to https://<app_name>.azurewebsites.net
.
Upewnij się, że nagłówki żądań są skonfigurowane tak, aby zawierały klucz apikey
i jego wartość, ustaw treść na nieprzetworzoną i użyj następującej zawartości zastępczej JSON:
{}
Powinieneś otrzymać 400 Bad Request
odpowiedź z usługi.
Uwaga
Nie można jeszcze przetestować interfejsu API przy użyciu prawidłowych danych żądania, ponieważ będzie to wymagało informacji specyficznych dla platformy z aplikacji .NET MAUI.
Aby uzyskać więcej informacji na temat wywoływania interfejsów API REST, zobacz Use .http files in Visual Studio and Test web APIs with the Http Repl (Używanie plików HTTP w programie Visual Studio i testowanie internetowych interfejsów API za pomocą protokołu Http Repl). W programie Visual Studio Code klient REST może służyć do testowania interfejsów API REST.
Stwórz aplikację .NET MAUI
W tej sekcji utworzysz aplikację .NET MAUI, która umożliwia rejestrację do otrzymywania powiadomień push z centrum powiadomień za pośrednictwem usługi backend oraz wyrejestrowanie się.
Aby utworzyć aplikację .NET MAUI:
W programie Visual Studio utwórz nową aplikację .NET MAUI o nazwie PushNotificationsDemo przy użyciu szablonu projektu .NET MAUI App .
W programie Visual Studio dodaj nowy folder o nazwie Models do projektu .NET MAUI, a następnie dodaj nową klasę o nazwie
DeviceInstallation
do folderu Models i zastąp jego kod następującym kodem: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>(); }
W programie Visual Studio dodaj wyliczenie o nazwie
PushDemoAction
do folderu Models i zastąp jego kod następującym kodem:namespace PushNotificationsDemo.Models; public enum PushDemoAction { ActionA, ActionB }
W programie Visual Studio dodaj nowy folder o nazwie Services do projektu .NET MAUI, a następnie dodaj nowy interfejs o nazwie
IDeviceInstallationService
do folderu Services i zastąp jego kod następującym kodem:using PushNotificationsDemo.Models; namespace PushNotificationsDemo.Services; public interface IDeviceInstallationService { string Token { get; set; } bool NotificationsSupported { get; } string GetDeviceId(); DeviceInstallation GetDeviceInstallation(params string[] tags); }
Ten interfejs zostanie zaimplementowany na każdej platformie później, aby udostępnić
DeviceInstallation
informacje wymagane przez usługę zaplecza.W programie Visual Studio dodaj interfejs o nazwie
INotificationRegistrationService
do folderu Services i zastąp jego kod następującym kodem:namespace PushNotificationsDemo.Services; public interface INotificationRegistrationService { Task DeregisterDeviceAsync(); Task RegisterDeviceAsync(params string[] tags); Task RefreshRegistrationAsync(); }
Ten interfejs będzie obsługiwać interakcję między klientem a usługą zaplecza.
W programie Visual Studio dodaj interfejs o nazwie
INotificationActionService
do folderu Services i zastąp jego kod następującym kodem:namespace PushNotificationsDemo.Services; public interface INotificationActionService { void TriggerAction(string action); }
Ten interfejs będzie używany jako prosty mechanizm umożliwiający scentralizowanie obsługi akcji powiadomień.
W programie Visual Studio dodaj interfejs o nazwie
IPushDemoNotificationActionService
do folderu Services i zastąp jego kod następującym kodem:using PushNotificationsDemo.Models; namespace PushNotificationsDemo.Services; public interface IPushDemoNotificationActionService : INotificationActionService { event EventHandler<PushDemoAction> ActionTriggered; }
Typ
IPushDemoNotificationActionService
jest specyficzny dla tej aplikacji i używa wyliczeniaPushDemoAction
do identyfikowania akcji, która jest wyzwalana za pomocą podejścia silnie typizowanego.W programie Visual Studio dodaj klasę o nazwie
NotificationRegistrationService
do folderu Services i zastąp jego kod następującym kodem: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(); } }
W programie Visual Studio dodaj klasę o nazwie
PushDemoNotificationActionService
do folderu Services i zastąp jego kod następującym kodem: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); } }
W programie Visual Studio dodaj klasę o nazwie
Config
do katalogu głównego projektu i zastąp jego kod następującym kodem:namespace PushNotificationsDemo; public static partial class Config { public static string ApiKey = "API_KEY"; public static string BackendServiceEndpoint = "BACKEND_SERVICE_ENDPOINT"; }
Klasa
Config
jest używana jako prosty sposób na przechowywanie tajemnic poza kontrolą źródła. Możesz zastąpić te wartości w ramach zautomatyzowanej kompilacji lub zastąpić je przy użyciu lokalnej klasy częściowej.Ważne
Podczas określania adresu podstawowego w aplikacji .NET MAUI upewnij się, że kończy się na .
/
W programie Visual Studio dodaj klasę o nazwie
Config.local_secrets
do katalogu głównego projektu. Następnie zastąp kod w pliku Config.local_secrets.cs następującym kodem:namespace PushNotificationsDemo; public static partial class Config { static Config() { ApiKey = "<your_api_key>"; BackendServiceEndpoint = "<your_api_app_url>"; } }
Zamień wartości symboli zastępczych na wartości wybrane podczas tworzenia usługi zaplecza. Adres
BackendServiceEndpoint
URL powinien używać formatuhttps://<api_app_name>.azurewebsites.net/
.Napiwek
Pamiętaj, aby dodać
*.local_secrets.*
do swojego pliku.gitignore
, aby uniknąć zatwierdzania tego pliku do systemu kontroli wersji.
Tworzenie interfejsu użytkownika
Aby utworzyć interfejs użytkownika aplikacji:
W programie Visual Studio otwórz plik
VerticalStackLayout
:<VerticalStackLayout Margin="20" Spacing="6"> <Button x:Name="registerButton" Text="Register" Clicked="OnRegisterButtonClicked" /> <Button x:Name="deregisterButton" Text="Deregister" Clicked="OnDeregisterButtonClicked" /> </VerticalStackLayout>
W programie Visual Studio otwórz MainPage.xaml.cs i dodaj instrukcję
using
dlaPushNotificationsDemo.Services
przestrzeni nazw:using PushNotificationsDemo.Services;
W MainPage.xaml.cs dodaj
readonly
pole zapasowe, aby zapisać odwołanie do implementacjiINotificationRegistrationService
:readonly INotificationRegistrationService _notificationRegistrationService;
W konstruktorze
MainPage
rozwiąż implementacjęINotificationRegistrationService
i przypisz ją do pola zapasowego_notificationRegistrationService
:public MainPage(INotificationRegistrationService service) { InitializeComponent(); _notificationRegistrationService = service; }
W klasie
MainPage
zaimplementujOnRegisterButtonClicked
iOnDeregisterButtonClicked
procedury obsługi zdarzeń, wywołując odpowiednie metody rejestrowania i wyrejestrowywania w obiekcieINotificationRegistrationService
.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; }); }); }
Ważne
W aplikacji rejestracja i anulowanie rejestracji jest wykonywana w odpowiedzi na dane wejściowe użytkownika, aby umożliwić łatwiejsze eksplorowanie i testowanie tej funkcji. W aplikacji produkcyjnej zazwyczaj wykonujesz akcje rejestracji i anulowania rejestracji w odpowiednim punkcie cyklu życia aplikacji bez konieczności jawnego wprowadzania danych przez użytkownika.
W programie Visual Studio otwórz App.xaml.cs i dodaj następujące
using
instrukcje:using PushNotificationsDemo.Models; using PushNotificationsDemo.Services;
W App.xaml.cs dodaj
readonly
pole zapasowe, aby zapisać odwołanie do implementacjiIPushDemoNotificationActionService
:readonly IPushDemoNotificationActionService _actionService;
W konstruktorze
App
rozwiąż implementacjęIPushDemoNotificationActionService
i przypisz ją do pola pomocniczego_actionService
, a następnie subskrybuj zdarzenieIPushDemoNotificationActionService.ActionTriggered
.public App(IPushDemoNotificationActionService service) { InitializeComponent(); _actionService = service; _actionService.ActionTriggered += NotificationActionTriggered; MainPage = new AppShell(); }
W konstruktorze
App
rozwiąż implementacjęIPushDemoNotificationActionService
, przypisz ją do pola pomocniczego_actionService
, a następnie zasubskrybuj zdarzenieIPushDemoNotificationActionService.ActionTriggered
.public App(IPushDemoNotificationActionService service) { InitializeComponent(); _actionService = service; _actionService.ActionTriggered += NotificationActionTriggered; }
W klasie
App
zaimplementuj procedurę obsługi zdarzeniaIPushDemoNotificationActionService.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; }); }); }
Obsługa zdarzenia dla zdarzenia
ActionTriggered
demonstruje odbieranie i propagację akcji powiadomień wypychanych. Zazwyczaj są one obsługiwane w trybie dyskretnym, na przykład przechodzenie do określonego widoku lub odświeżanie niektórych danych zamiast wyświetlania alertu.
Konfigurowanie aplikacji systemu Android
Aby skonfigurować aplikację .NET MAUI w systemie Android do odbierania i przetwarzania powiadomień push:
W programie Visual Studio dodaj pakiet NuGet Xamarin.Firebase.Messaging do projektu aplikacji .NET MAUI.
W programie Visual Studio dodaj plik google-services.json do folderu Platformy/Android projektu aplikacji .NET MAUI. Po dodaniu pliku do projektu powinien on zostać dodany z akcją kompilacji typu
GoogleServicesJson
.<ItemGroup Condition="'$(TargetFramework)' == 'net8.0-android'"> <GoogleServicesJson Include="Platforms\Android\google-services.json" /> </ItemGroup>
Napiwek
Pamiętaj, aby dodać
google-services.json
do pliku.gitignore
, aby uniknąć zatwierdzania tego pliku do systemu kontroli wersji.W programie Visual Studio edytuj plik projektu (*.csproj) i ustaw
SupportedOSPlatformVersion
dla systemu Android wartość 26.0:<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">26.0</SupportedOSPlatformVersion>
Google dokonało zmian w kanałach powiadomień systemu Android w interfejsie API 26. Aby uzyskać więcej informacji, zobacz Kanały powiadomień w developer.android.com.
W folderze Platformy/Android projektu dodaj nową klasę o nazwie
DeviceInstallationService
i zastąp jej kod następującym kodem: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."; } }
Ta klasa zapewnia unikatowy identyfikator, korzystając z wartości
Secure.AndroidId
i ładunku rejestracyjnego centrum powiadomień.W folderze Platformy/Android projektu dodaj nową klasę o nazwie
PushNotificationFirebaseMessagingService
i zastąp jej kod następującym kodem: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); } }
Ta klasa ma
IntentFilter
atrybut zawierającycom.google.firebase.MESSAGING_EVENT
filtr. Ten filtr umożliwia systemowi Android przekazywanie przychodzących komunikatów do tej klasy na potrzeby przetwarzania.Aby uzyskać informacje o formacie komunikatów Firebase Cloud Messaging, zobacz Informacje o komunikatach FCM na developer.android.com.
W programie Visual Studio otwórz plik MainActivity.cs w folderze Platformy/Android i dodaj następujące
using
instrukcje:using Android.App; using Android.Content; using Android.Content.PM; using Android.OS; using PushNotificationsDemo.Services; using Firebase.Messaging;
W klasie
MainActivity
ustawLaunchMode
naSingleTop
, abyMainActivity
nie został utworzony ponownie po otwarciu:[Activity( Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
W klasie
MainActivity
dodaj pola zapasowe do przechowywania odwołań do implementacjiIPushDemoNotificationActionService
iIDeviceInstallationService
.IPushDemoNotificationActionService _notificationActionService; IDeviceInstallationService _deviceInstallationService;
W klasie
MainActivity
dodajNotificationActionService
iDeviceInstallationService
właściwości prywatne, które pobierają swoje konkretne implementacje z kontenera iniekcji zależności aplikacji.IPushDemoNotificationActionService NotificationActionService => _notificationActionService ?? (_notificationActionService = IPlatformApplication.Current.Services.GetService<IPushDemoNotificationActionService>()); IDeviceInstallationService DeviceInstallationService => _deviceInstallationService ?? (_deviceInstallationService = IPlatformApplication.Current.Services.GetService<IDeviceInstallationService>());
W klasie zaimplementuj
MainActivity
Android.Gms.Tasks.IOnSuccessListener
interfejs w celu pobrania i zapisania tokenu Firebase:public class MainActivity : MauiAppCompatActivity, Android.Gms.Tasks.IOnSuccessListener { public void OnSuccess(Java.Lang.Object result) { DeviceInstallationService.Token = result.ToString(); } }
W klasie
MainActivity
dodaj metodęProcessNotificationActions
, która sprawdzi, czy daneIntent
ma dodatkową wartość o nazwieaction
, a następnie warunkowo uruchomaction
przy użyciu implementacjiIPushDemoNotificationActionService
: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); } }
MainActivity
W klasie zastąpij metodęOnNewIntent
, aby wywołać metodęProcessNotificationActions
:protected override void OnNewIntent(Intent? intent) { base.OnNewIntent(intent); ProcessNotificationsAction(intent); }
Ponieważ dla
Activity
jest ustawiona wartośćSingleTop
, elementIntent
zostanie wysłany do istniejącego wystąpieniaActivity
poprzez przesłonięcieOnNewIntent
, a nie metodąOnCreate
. W związku z tym należy obsługiwać intencję przychodzącą zarówno wOnNewIntent
, jak iOnCreate
.W klasie
MainActivity
zastąp metodęOnCreate
, aby wywołać metodęProcessNotificationActions
i pobrać token z Firebase, dodającMainActivity
jakoIOnSuccessListener
.protected override void OnCreate(Bundle? savedInstanceState) { base.OnCreate(savedInstanceState); if (DeviceInstallationService.NotificationsSupported) FirebaseMessaging.Instance.GetToken().AddOnSuccessListener(this); ProcessNotificationsAction(Intent); }
Uwaga
Aplikacja musi być ponownie zarejestrowana za każdym razem, gdy jest uruchamiana, oraz zatrzymana podczas sesji debugowania, aby nadal otrzymywać powiadomienia push.
W programie Visual Studio dodaj
POST_NOTIFICATIONS
uprawnienie do pliku AndroidManifest.xml w folderze Platformy/Android :<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
Aby uzyskać więcej informacji na temat tego uprawnienia, zobacz Uprawnienia środowiska uruchomieniowego powiadomień w developer.android.com.
W programie Visual Studio otwórz MainPage.xaml.cs i dodaj następujący kod do
MainPage
klasy:#if ANDROID protected override async void OnAppearing() { base.OnAppearing(); PermissionStatus status = await Permissions.RequestAsync<Permissions.PostNotifications>(); } #endif
Ten kod działa na Androidzie, kiedy pojawi się
MainPage
, i prosi użytkownika o udzielenie uprawnieńPOST_NOTIFICATIONS
. Aby uzyskać więcej informacji na temat uprawnień programu .NET MAUI, zobacz Uprawnienia.
Konfigurowanie aplikacji systemu iOS
Symulator systemu iOS obsługuje powiadomienia zdalne w systemie iOS 16 lub nowszym podczas uruchamiania w systemie macOS 13 lub nowszym na komputerach Mac z procesorami krzemowymi firmy Apple lub T2. Każdy symulator generuje tokeny rejestracji, które są unikatowe dla kombinacji tego symulatora i sprzętu mac, na którym działa.
Ważne
Symulator obsługuje środowisko testowe (sandbox) usługi Apple Push Notification Service.
W poniższych instrukcjach założono, że używasz sprzętu obsługującego odbieranie powiadomień zdalnych w symulatorze systemu iOS. Jeśli tak nie jest, musisz uruchomić aplikację systemu iOS na urządzeniu fizycznym, co będzie wymagało utworzenia profilu aprowizacji dla aplikacji, która obejmuje funkcjonalność powiadomień push. Następnie należy upewnić się, że aplikacja została skompilowana przy użyciu certyfikatu i profilu provisioningowego. Aby uzyskać więcej informacji na temat tego, jak to zrobić, zobacz Konfigurowanie aplikacji systemu iOS do pracy z usługą Azure Notification Hubs, a następnie postępuj zgodnie z poniższymi instrukcjami.
Aby skonfigurować aplikację .NET MAUI w systemie iOS w celu odbierania i przetwarzania powiadomień push:
W programie Visual Studio edytuj plik projektu (*.csproj) i ustaw
SupportedOSPlatformVersion
dla systemu iOS wartość 13.0:<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">13.0</SupportedOSPlatformVersion>
Firma Apple dokonała zmian w swojej usłudze powiadomień push w systemie iOS 13. Aby uzyskać więcej informacji, zobacz Aktualizacje usługi Azure Notification Hubs dla systemu iOS 13.
W programie Visual Studio dodaj plik Entitlements.plist do folderu Platforms/iOS projektu i dodaj następujący kod XML do pliku:
<?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>
Ustawienie uprawnień środowiska usługi APS i wskazuje na użycie środowiska deweloperskiego Apple Push Notification Service. W aplikacjach produkcyjnych to uprawnienie powinno być ustawione na
production
. Aby uzyskać więcej informacji na temat tego uprawnienia, zobacz APS Environment Entitlement na developer.apple.com.Aby uzyskać więcej informacji na temat dodawania pliku uprawnień, zobacz uprawnienia systemu iOS.
W programie Visual Studio dodaj nową klasę o nazwie
DeviceInstallationService
do folderu Platformy/iOS projektu i dodaj następujący kod do pliku: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"; } }
Ta klasa udostępnia unikatowy identyfikator, używając wartości
UIDevice.IdentifierForVendor
i danych rejestracji centrum powiadamiania.W programie Visual Studio dodaj nową klasę o nazwie
NSDataExtensions
do folderu Platformy/iOS projektu i dodaj następujący kod do pliku: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(); } }
Metoda rozszerzenia
ToHexString
będzie wykorzystywana przez kod, jaki dodasz, aby analizować pobrany token urządzenia.W programie Visual Studio otwórz plik AppDelegate.cs w folderze Platformy/iOS i dodaj następujące
using
instrukcje:using System.Diagnostics; using Foundation; using PushNotificationsDemo.Platforms.iOS; using PushNotificationsDemo.Services; using UIKit; using UserNotifications;
W klasie
AppDelegate
dodaj pola zapasowe do przechowywania odwołań do implementacjiIPushDemoNotificationActionService
,INotificationRegistrationService
iIDeviceInstallationService
.IPushDemoNotificationActionService _notificationActionService; INotificationRegistrationService _notificationRegistrationService; IDeviceInstallationService _deviceInstallationService;
W klasie
AppDelegate
dodaj prywatne właściwościNotificationActionService
,NotificationRegistrationService
iDeviceInstallationService
, które pobierają swoje konkretne implementacje z kontenera wstrzykiwania zależności aplikacji.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>());
W klasie
AppDelegate
dodaj metodęCompleteRegistrationAsync
, aby ustawić wartość właściwościIDeviceInstallationService.Token
:Task CompleteRegistrationAsync(NSData deviceToken) { DeviceInstallationService.Token = deviceToken.ToHexString(); return NotificationRegistrationService.RefreshRegistrationAsync(); }
Ta metoda odświeża również rejestrację i buforuje token urządzenia, jeśli został on zaktualizowany od czasu jego ostatniego przechowywania.
W klasie
AppDelegate
, dodaj metodęProcessNotificationActions
do przetwarzania danych powiadomieńNSDictionary
i warunkowego wywołaniaNotificationActionService.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); } }
AppDelegate
W klasie dodaj metodęRegisteredForRemoteNotifications
przekazującądeviceToken
argument doCompleteRegistrationAsync
metody :[Export("application:didRegisterForRemoteNotificationsWithDeviceToken:")] public void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken) { CompleteRegistrationAsync(deviceToken) .ContinueWith((task) => { if (task.IsFaulted) throw task.Exception; }); }
Ta metoda zostanie wywołana, gdy aplikacja zostanie zarejestrowana w celu odbierania powiadomienia zdalnego i będzie używana do żądania unikatowego tokenu urządzenia, który jest w rzeczywistości adresem aplikacji na urządzeniu.
AppDelegate
W klasie dodaj metodęReceivedRemoteNotification
przekazującąuserInfo
argument doProcessNotificationActions
metody :[Export("application:didReceiveRemoteNotification:")] public void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo) { ProcessNotificationActions(userInfo); }
Ta metoda będzie wywoływana, gdy aplikacja otrzymała powiadomienie zdalne i jest używana do przetwarzania powiadomienia.
AppDelegate
W klasie dodaj metodęFailedToRegisterForRemoteNotifications
, aby rejestrować błędy:[Export("application:didFailToRegisterForRemoteNotificationsWithError:")] public void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error) { Debug.WriteLine(error.Description); }
Ta metoda zostanie wywołana, gdy aplikacja nie może zarejestrować się w celu odbierania powiadomień zdalnych. Rejestracja może zakończyć się niepowodzeniem, jeśli urządzenie nie jest połączone z siecią, jeśli serwer APNS jest niemożliwy do osiągnięcia lub jeśli aplikacja jest niepoprawnie skonfigurowana.
Uwaga
W przypadku scenariuszy produkcyjnych należy zaimplementować odpowiednie rejestrowanie i obsługę błędów w metodzie
FailedToRegisterForRemoteNotifications
.AppDelegate
W klasie dodaj metodęFinishedLaunching
, aby warunkowo zażądać uprawnień do korzystania z powiadomień i zarejestrować się w celu otrzymywania powiadomień zdalnych:[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); }
Aby uzyskać informacje na temat proszenia o zgodę na korzystanie z powiadomień, zobacz Prośba o zgodę na korzystanie z powiadomień na developer.apple.com.
Aby uzyskać informacje o powiadomieniach w systemie iOS, zobacz Powiadomienia użytkowników w developer.apple.com.
Rejestrowanie typów w kontenerze wstrzykiwania zależności aplikacji
W programie Visual Studio otwórz MauiProgram.cs i dodaj instrukcję
using
dlaPushNotificationsDemo.Services
przestrzeni nazw:using PushNotificationsDemo.Services;
W klasie
MauiProgram
dodaj kod dla metody rozszerzeniaRegisterServices
, która rejestrujeDeviceInstallationService
na każdej platformie, oraz usługi międzyplatformowePushDemoNotificationActionService
iNotificationRegistrationService
, i zwraca obiekt typuMauiAppBuilder
: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; }
W klasie
MauiProgram
dodaj kod dla metody rozszerzeniaRegisterViews
, która rejestruje typMainPage
jako singleton i zwraca obiektMauiAppBuilder
.public static MauiAppBuilder RegisterViews(this MauiAppBuilder builder) { builder.Services.AddSingleton<MainPage>(); return builder; }
Typ
MainPage
jest zarejestrowany, ponieważ wymagaINotificationRegistrationService
zależności, a wszystkie typy wymagające zależności muszą być zarejestrowane w kontenerze wstrzykiwania zależności.W klasie
MauiProgram
zmodyfikuj metodęCreateMauiApp
, tak aby wywołała metody rozszerzeniaRegisterServices
iRegisterViews
.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(); }
Aby uzyskać więcej informacji na temat wstrzykiwania zależności w programie .NET MAUI, zobacz Wstrzykiwanie zależności.
Testowanie aplikacji
Możesz przetestować swoją aplikację, wysyłając powiadomienia push do aplikacji przy użyciu zaplecza usług lub za pośrednictwem portalu Azure.
Symulator systemu iOS obsługuje powiadomienia zdalne w systemie iOS 16 lub nowszym podczas uruchamiania w systemie macOS 13 lub nowszym na komputerach Mac z procesorami krzemowymi firmy Apple lub T2. Jeśli nie spełniasz tych wymagań sprzętowych, musisz przetestować aplikację systemu iOS na urządzeniu fizycznym. W systemie Android możesz przetestować aplikację na odblokowanym urządzeniu fizycznym dewelopera lub emulatorze.
Systemy Android i iOS wyświetlają powiadomienia push w imieniu aplikacji, gdy jest uruchomiona w tle. Jeśli aplikacja jest uruchomiona na pierwszym planie po odebraniu powiadomienia, kod aplikacji określa zachowanie. Możesz na przykład zaktualizować interfejs aplikacji, aby odzwierciedlić nowe informacje zawarte w powiadomieniu.
Testowanie przy użyciu usługi zaplecza
Aby wysłać testowe powiadomienie push do aplikacji za pośrednictwem usługi backendowej opublikowanej w usłudze Azure App Service.
W programie Visual Studio uruchom aplikację PushNotificationsDemo w systemie Android lub iOS i wybierz przycisk Zarejestruj .
Uwaga
Jeśli testujesz w systemie Android, upewnij się, że nie używasz konfiguracji debugowania. Alternatywnie, jeśli aplikacja została wcześniej wdrożona, upewnij się, że została zamknięta, a następnie uruchom ją ponownie z poziomu uruchamiania.
W wybranym narzędziu REST wyślij
POST
żądanie na następujący adres:https://<app_name>.azurewebsites.net/api/notifications/requests
Upewnij się, że nagłówki żądania są skonfigurowane tak, aby zawierały klucz
apikey
i jego wartość, ustaw ciało żądania jako surowe i użyj następującego kodu JSON.{ "text": "Message from REST tooling!", "action": "action_a" }
Ogólne żądanie powinno być podobne do następującego przykładu:
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" }
W wybranym narzędziu REST sprawdź, czy otrzymasz odpowiedź 200 OK .
W aplikacji w systemie Android lub iOS powinien zostać wyświetlony alert z odebraną akcją ActionA.
Aby uzyskać więcej informacji na temat wywoływania interfejsów API REST, zobacz Use .http files in Visual Studio and Test web APIs with the Http Repl (Używanie plików HTTP w programie Visual Studio i testowanie internetowych interfejsów API za pomocą protokołu Http Repl). W programie Visual Studio Code klient REST może służyć do testowania interfejsów API REST.
Testowanie przy użyciu witryny Azure Portal
Usługa Azure Notification Hubs umożliwia sprawdzenie, czy aplikacja może odbierać powiadomienia push.
Aby wysłać testowe powiadomienie push do aplikacji za pośrednictwem portalu Azure:
W programie Visual Studio uruchom aplikację PushNotificationsDemo w systemie Android lub iOS i wybierz przycisk Zarejestruj .
Uwaga
Jeśli testujesz w systemie Android, upewnij się, że nie używasz konfiguracji debugowania. Alternatywnie, jeśli aplikacja została wcześniej wdrożona, upewnij się, że została zamknięta, a następnie uruchom ją ponownie z poziomu uruchamiania.
W portalu Azure przejdź do centrum powiadomień i wybierz przycisk Testowe Wysyłanie na ostrzu Przegląd.
W bloku Wysyłanie testowe wybierz wymaganą platformę i zmodyfikuj ładunek.
W przypadku firmy Apple użyj następującego ładunku:
{ "aps": { "alert": "Message from Notification Hub!" }, "action": "action_a" }
W przypadku systemu Android użyj następującego ładunku danych:
{ "message": { "notification": { "title": "PushDemo", "body": "Message from Notification Hub!" }, "data": { "action": "action_a" } } }
Witryna Azure Portal powinna wskazywać, że powiadomienie zostało pomyślnie wysłane.
Aby uzyskać informacje o formacie komunikatów Firebase Cloud Messaging, zobacz Informacje o komunikatach FCM na stronie developer.android.com.
W aplikacji w systemie Android lub iOS powinien zostać wyświetlony alert z odebraną akcją ActionA.
Rozwiązywanie problemów
W poniższych sekcjach omówiono typowe problemy napotykane podczas korzystania z powiadomień push w aplikacji klienckiej.
Brak odpowiedzi z usługi zaplecza
Podczas testowania lokalnego upewnij się, że usługa zaplecza jest uruchomiona i używa poprawnego portu.
W przypadku testowania aplikacji interfejsu API platformy Azure sprawdź, czy usługa została wdrożona i działa bez błędów.
Upewnij się, że adres podstawowy został poprawnie określony w narzędziu REST lub w konfiguracji aplikacji .NET MAUI. Adres podstawowy powinien być https://<api_name>.azurewebsites.net
lub https://localhost:7020
podczas testowania lokalnego.
Odbieranie kodu stanu 401 z usługi zaplecza
Sprawdź, czy poprawnie ustawiasz apikey
nagłówek żądania i czy ta wartość jest zgodna z wartością skonfigurowaną dla usługi zaplecza.
Jeśli ten błąd pojawia się podczas testowania lokalnego, upewnij się, że wartość klucza, którą zdefiniowałeś w aplikacji .NET MAUI, odpowiada wartości tajnych danych użytkownika określonych jako Authentication:ApiKey
i używanych przez usługę zaplecza.
Jeśli testujesz przy użyciu aplikacji interfejsu API platformy Azure, upewnij się, że wartość klucza zdefiniowana w aplikacji .NET MAUI jest zgodna Authentication:ApiKey
z wartością ustawienia aplikacji zdefiniowaną w witrynie Azure Portal. Jeśli to ustawienie aplikacji zostało utworzone lub zmienione po wdrożeniu usługi zaplecza, musisz ponownie uruchomić usługę, aby wartość została wdrożona.
Odbieranie kodu stanu 404 z usługi zaplecza
Sprawdź, czy punkt końcowy i metoda żądania HTTP są poprawne:
- Umieść -
https://<api_name>.azurewebsites.net/api/notifications/installations
- Usuń -
https://<api_name>.azurewebsites.net/api/notifications/installations/<installation_id>
- POST-
https://<api_name>.azurewebsites.net/api/notifications/requests
Lub podczas testowania lokalnego:
- PUT -
https://localhost:7020/api/notifications/installations
- USUNĄĆ -
https://localhost:7020/api/notifications/installations/<installation_id>
- POST-
https://localhost:7020/api/notifications/requests
Ważne
Podczas określania adresu podstawowego w aplikacji .NET MAUI upewnij się, że kończy się na ./
Adres podstawowy powinien być https://<api_name>.azurewebsites.net
lub https://localhost:7020/
podczas testowania lokalnego.
Nie otrzymuję powiadomień w systemie Android po uruchomieniu lub zatrzymaniu sesji debugowania
Upewnij się, że rejestrujesz się za każdym razem, gdy rozpoczynasz sesję debugowania. Debuger spowoduje wygenerowanie nowego tokenu programu Firebase, dlatego należy zaktualizować instalację centrum powiadomień.
Nie można zarejestrować i zostanie wyświetlony komunikat o błędzie centrum powiadomień
Sprawdź, czy urządzenie testowe ma łączność sieciową. Następnie określ kod stanu odpowiedzi HTTP, ustawiając punkt przerwania, aby sprawdzić właściwość StatusCode
w HttpResponse
.
Przejrzyj poprzednie sugestie dotyczące rozwiązywania problemów, jeśli ma to zastosowanie, na podstawie kodu stanu.
Ustaw punkt przerwania w wierszach, które zwracają określone kody stanu odpowiedniego interfejsu API. Następnie spróbuj wywołać usługę zaplecza podczas lokalnego debugowania.
Zweryfikuj, czy usługa zaplecza działa zgodnie z oczekiwaniami według wybranego narzędzia REST, i użyj ładunku utworzonego przez aplikację .NET MAUI dla wybranej platformy.
Przejrzyj sekcje konfiguracji specyficzne dla platformy, aby upewnić się, że nie pominięto żadnych kroków. Sprawdź, czy dla zmiennych InstallationId
i Token
odpowiednie wartości są ustawiane na wybraną platformę.
Nie można rozpoznać identyfikatora urządzenia w komunikacie o błędzie urządzenia
Przejrzyj sekcje konfiguracji specyficzne dla platformy, aby upewnić się, że nie pominięto żadnych kroków.