Sdílet prostřednictvím


Kurz: Odesílání nabízených oznámení do aplikací Flutter pomocí Služby Azure Notification Hubs prostřednictvím back-endové služby

Stáhnout ukázku Stažení ukázky

V tomto kurzu použijete Azure Notification Hubs k nabízeným oznámením do aplikace Flutter , která cílí na Android a iOS.

Back-end webového rozhraní API ASP.NET Core se používá ke zpracování registrace zařízení pro klienta pomocí nejnovějšího a nejlepšího přístupu k instalaci. Služba bude také odesílat nabízená oznámení multiplatformně.

Tyto operace se zpracovávají pomocí sady Notification Hubs SDK pro back-endové operace. Další podrobnosti o celkovém přístupu najdete v dokumentaci k registraci z back-endu aplikace .

Tento kurz vás provede následujícími kroky:

Požadavky

Pokud chcete postup sledovat, potřebujete:

Pro Android musíte mít:

  • Odemčené fyzické zařízení nebo emulátor od vývojáře (s rozhraním API 26 a novějším a nainstalovanými službami Google Play)

Pro iOS musíte mít:

Poznámka

Simulátor iOS nepodporuje vzdálená oznámení, a proto se při zkoumání této ukázky v iOSu vyžaduje fyzické zařízení. K dokončení tohoto kurzu ale nemusíte aplikaci spouštět na Androidu i v iOSu .

Můžete postupovat podle kroků v tomto příkladu s prvními principy bez předchozích zkušeností. Pro vás ale bude výhodné, když se seznámíte s následujícími aspekty.

Uvedené kroky jsou specifické pro macOS. Ve Windows můžete pokračovat přeskočením aspektů iOSu .

Nastavení služeb nabízených oznámení a Centra oznámení Azure

V této části nastavíte službu Firebase Cloud Messaging (FCM) a službu Apple Push Notification Services (APNS). Pak vytvoříte a nakonfigurujete centrum oznámení pro práci s těmito službami.

Vytvoření projektu Firebase a povolení služby Firebase Cloud Messaging pro Android

  1. Přihlaste se ke konzole Firebase. Vytvořte nový projekt Firebase a jako název projektu zadejte PushDemo.

    Poznámka

    Vygeneruje se pro vás jedinečný název. Ve výchozím nastavení se skládá z malé varianty zadaného názvu a vygenerovaného čísla odděleného pomlčkou. Pokud chcete, můžete ho změnit, pokud je stále globálně jedinečný.

  2. Po vytvoření projektu vyberte Přidat Firebase do aplikace pro Android.

    Přidání Firebase do aplikace pro Android

  3. Na stránce Přidat Firebase do aplikace pro Android proveďte následující kroky.

    1. Jako název balíčku pro Android zadejte název balíčku. Příklad: com.<organization_identifier>.<package_name>.

      Zadejte název balíčku.

    2. Vyberte Zaregistrovat aplikaci.

    3. Vyberte Stáhnout google-services.json. Pak soubor uložte do místní složky pro pozdější použití a vyberte Další.

      Stáhnout google-services.json

    4. Vyberte Další.

    5. Vyberte Pokračovat do konzoly.

      Poznámka

      Pokud tlačítko Pokračovat do konzoly není povolené kvůli kontrole ověření instalace , zvolte Přeskočit tento krok.

  4. V konzole Firebase vyberte ozubené kolo pro váš projekt. Pak vyberte Nastavení projektu.

    Vyberte Nastavení projektu.

    Poznámka

    Pokud jste si soubor google-services.json nestáhli, můžete si ho stáhnout na této stránce.

  5. V horní části přepněte na cloudovou kartu Zasílání zpráv . Zkopírujte a uložte klíč serveru pro pozdější použití. Tuto hodnotu použijete ke konfiguraci centra oznámení.

    Kopírování klíče serveru

Registrace aplikace pro iOS pro nabízená oznámení

Pokud chcete odesílat nabízená oznámení do aplikace pro iOS, zaregistrujte aplikaci u společnosti Apple a také zaregistrujte nabízená oznámení.

  1. Pokud jste aplikaci ještě nezaregistrovali, přejděte na portál zřizování pro iOS v Centru pro vývojáře Apple. Přihlaste se k portálu pomocí svého Apple ID, přejděte na Certifikáty, Identifikátory & Profily a pak vyberte Identifikátory. Kliknutím + zaregistrujete novou aplikaci.

    Stránka ID aplikací portálu zřizování pro iOS

  2. Na obrazovce Register a New Identifier (Zaregistrovat nový identifikátor ) vyberte přepínač ID aplikací . Pak vyberte Pokračovat.

    Registrace nové stránky ID na portálu zřizování pro iOS

  3. Aktualizujte pro novou aplikaci následující tři hodnoty a pak vyberte Pokračovat:

    • Popis: Zadejte popisný název aplikace.

    • ID sady: Zadejte ID balíčku formuláře com.organization_identifier<>.<>product_name, jak je uvedeno v průvodci distribucí aplikací. Na následujícím snímku obrazovky mobcat se hodnota použije jako identifikátor organizace a jako název produktu se použije hodnota PushDemo .

      Stránka registrace ID aplikace na portálu zřizování pro iOS

    • Nabízená oznámení: V části Možnosti zaškrtněte možnost Nabízenáoznámení.

      Formulář pro registraci nového ID aplikace

      Tato akce vygeneruje ID aplikace a požádá o potvrzení informací. Vyberte Pokračovat a pak vyberte Zaregistrovat a potvrďte nové ID aplikace.

      Potvrzení nového ID aplikace

      Po výběru možnosti Zaregistrovat se nové ID aplikace zobrazí jako řádková položka na stránce Certifikáty, identifikátory & profily .

  4. Na stránce Certifikáty, identifikátory & profily vyhledejte v části Identifikátory položku řádku ID aplikace, kterou jste vytvořili. Pak vyberte jeho řádek, aby se zobrazila obrazovka Upravit konfiguraci ID aplikace .

Vytvoření certifikátu pro Notification Hubs

Certifikát se vyžaduje k tomu, aby centrum oznámení fungovalo se službou Apple Push Notification Services (APNS), a dá se poskytnout jedním ze dvou způsobů:

  1. Vytvoření nabízeného certifikátu p12, který je možné nahrát přímo do centra oznámení (původní přístup)

  2. Vytvoření certifikátu p8, který se dá použít k ověřování na základě tokenů (novější a doporučený přístup)

Novější přístup má řadu výhod, které jsou popsané v tématu Ověřování APNS na základě tokenů (HTTP/2). Vyžaduje se méně kroků, ale je to také povinné pro konkrétní scénáře. Pro oba přístupy však byly poskytnuty kroky, protože pro účely tohoto kurzu bude fungovat jeden z těchto přístupů.

MOŽNOST 1: Vytvoření nabízeného certifikátu p12, který je možné nahrát přímo do centra oznámení
  1. Na počítači Mac spusťte nástroj Klíčenky. Můžete ho otevřít ze složky Utility nebo ze složky Jiné na hlavním panelu.

  2. Vyberte Přístup ke svazku klíčů, rozbalte Pomocník s certifikáty a pak vyberte Požádat o certifikát od certifikační autority.

    Žádost o nový certifikát pomocí klíčenky

    Poznámka

    Ve výchozím nastavení vybere přístup řetězce klíčů první položku v seznamu. To může být problém, pokud jste v kategorii Certifikáty a certifikační autorita Apple Worldwide Developer Relations Certifikační autorita není první položkou v seznamu. Před vygenerováním žádosti o podepsání certifikátu (CERTIFICATE Signing Request) se ujistěte, že máte položku, která není klíčem, nebo že je vybraný klíč certifikační autority Apple Worldwide Developer Relations .

  3. Vyberte adresu Email uživatele, zadejte hodnotu Běžný název, ujistěte se, že jste zadali Možnost Uloženo na disk, a pak vyberte Pokračovat. Adresu Email certifikační autority ponechte prázdnou, protože se nevyžaduje.

    Očekávané informace o certifikátu

  4. Zadejte název souboru žádosti o podepsání certifikátu (CSR) do pole Uložit jako, vyberte umístění v části Kde a pak vyberte Uložit.

    Zvolte název souboru pro certifikát.

    Tato akce uloží soubor CSR do vybraného umístění. Výchozí umístění je Plocha. Zapamatujte si umístění zvolené pro soubor.

  5. Vraťte se na stránku Certifikáty, identifikátory & profily na portálu pro zřizování iOS, posuňte se dolů k zaškrtnuté možnosti Nabízená oznámení a pak výběrem možnosti Konfigurovat vytvořte certifikát.

    Stránka Upravit ID aplikace

  6. Zobrazí se okno Certifikáty TLS/SSL služby Apple Push Notification . V části Vývoj certifikátu TLS/SSL vyberte tlačítko Vytvořit certifikát.

    Tlačítko Vytvořit certifikát pro ID aplikace

    Zobrazí se obrazovka Vytvořit nový certifikát .

    Poznámka

    Tento kurz používá certifikát pro vývoj. Stejný postup se používá při registraci produkčního certifikátu. Jen se ujistěte, že při odesílání oznámení používáte stejný typ certifikátu.

  7. Vyberte Zvolit soubor, přejděte do umístění, kam jste soubor CSR uložili, a potom poklikáním na název certifikátu ho načtěte. Pak vyberte Pokračovat.

  8. Jakmile portál vytvoří certifikát, vyberte tlačítko Stáhnout . Uložte certifikát a zapamatujte si umístění, do kterého je uložený.

    Stránka pro stažení vygenerovaného certifikátu

    Certifikát se stáhne a uloží do počítače ve složce Stažené soubory .

    Vyhledejte soubor certifikátu ve složce Stažené soubory.

    Poznámka

    Ve výchozím nastavení má stažený vývojový certifikát název aps_development.cer.

  9. Poklikejte na stažený certifikát push certificate aps_development.cer. Tato akce nainstaluje nový certifikát do klíčenky, jak je znázorněno na následujícím obrázku:

    Seznam přístupových certifikátů pro řetězce klíčů zobrazující nový certifikát

    Poznámka

    I když se název v certifikátu může lišit, název bude mít předponu Apple Development iOS Push Services a bude k němu přidružený příslušný identifikátor sady.

  10. V části Přístup ke klíčovněklikněte + na nový certifikát push, který jste vytvořili v kategorii Certifikáty. Vyberte Exportovat, pojmenujte soubor, vyberte formát p12 a pak vyberte Uložit.

    Export certifikátu ve formátu p12

    Certifikát můžete chránit heslem, ale heslo je volitelné. Pokud chcete obejít vytváření hesla, klikněte na OK . Poznamenejte si název souboru a umístění exportovaného certifikátu p12. Používají se k povolení ověřování pomocí služby APN.

    Poznámka

    Název a umístění vašeho souboru p12 se může lišit od toho, co je znázorněno v tomto kurzu.

MOŽNOST 2: Vytvoření certifikátu p8, který se dá použít k ověřování na základě tokenů
  1. Poznamenejte si následující podrobnosti:

    • Předpona ID aplikace (ID týmu)
    • ID sady
  2. Zpět v části Certifikáty, Identifikátory & Profily klikněte na Klíče.

    Poznámka

    Pokud už máte klíč pro APNS nakonfigurovaný, můžete znovu použít certifikát p8, který jste stáhli hned po jeho vytvoření. Pokud ano, můžete kroky 35 ignorovat.

  3. Kliknutím na + tlačítko (nebo na tlačítko Vytvořit klíč ) vytvořte nový klíč.

  4. Zadejte vhodnou hodnotu názvu klíče , pak zaškrtněte možnost Služba Apple Push Notifications (APNS) a na další obrazovce klikněte na Pokračovat a pak na Zaregistrovat .

  5. Klikněte na Stáhnout , přesuňte soubor p8 (s předponou AuthKey_) do zabezpečeného místního adresáře a klikněte na Hotovo.

    Poznámka

    Soubor p8 uchovávejte na bezpečném místě (a uložte si zálohu). Po stažení není možné klíč znovu stáhnout, protože se odebere serverová kopie.

  6. V části Klíče klikněte na klíč, který jste vytvořili (nebo na existující klíč, pokud jste se ho rozhodli použít).

  7. Poznamenejte si hodnotu ID klíče .

  8. Otevřete certifikát p8 ve vhodné aplikaci podle vašeho výběru, jako je Visual Studio Code. Poznamenejte si hodnotu klíče (mezi -----BEGIN PRIVATE KEY----- a -----END PRIVATE KEY-----).

    -----BEGIN PRIVATE KEY-----
    <key_value>
    -----END PRIVÁTNÍ KLÍČ-----

    Poznámka

    Toto je hodnota tokenu , která se později použije ke konfiguraci centra oznámení.

Na konci těchto kroků byste měli mít následující informace pro pozdější použití v části Konfigurace centra oznámení s informacemi O APNS:

  • ID týmu (viz krok 1)
  • ID sady prostředků (viz krok 1)
  • ID klíče (viz krok 7)
  • Hodnota tokenu (hodnota klíče p8 získaná v kroku 8)

Vytvoření zřizovacího profilu pro aplikaci

  1. Vraťte se na portál pro zřizování iOS, vyberte Certifikáty, identifikátory & profily, v nabídce vlevo vyberte Profily a pak výběrem vytvořte + nový profil. Zobrazí se obrazovka Zaregistrovat nový zřizovací profil .

  2. Jako typ zřizovacího profilu v části Vývoj vyberte Vývoj aplikací pro iOS a pak vyberte Pokračovat.

    Seznam zřizovacích profilů

  3. Pak v rozevíracím seznamu ID aplikace vyberte ID aplikace, které jste vytvořili, a vyberte Pokračovat.

    Vyberte ID aplikace.

  4. V okně Vybrat certifikáty vyberte certifikát pro vývoj, který používáte k podepisování kódu, a vyberte Pokračovat.

    Poznámka

    Tento certifikát není certifikátem push, který jste vytvořili v předchozím kroku. Toto je váš certifikát pro vývoj. Pokud neexistuje, musíte ho vytvořit, protože se jedná o předpoklad pro tento kurz. Certifikáty pro vývojáře je možné vytvářet na portálu Pro vývojáře Apple, prostřednictvím Xcode nebo v sadě Visual Studio.

  5. Vraťte se na stránku Certifikáty, identifikátory & profily , v nabídce vlevo vyberte Profily a pak výběrem vytvořte + nový profil. Zobrazí se obrazovka Zaregistrovat nový zřizovací profil .

  6. V okně Vybrat certifikáty vyberte certifikát pro vývoj, který jste vytvořili. Pak vyberte Pokračovat.

  7. Dále vyberte zařízení, která chcete použít k testování, a vyberte Pokračovat.

  8. Nakonec zvolte název profilu v části Název zřizovacího profilu a vyberte Vygenerovat.

    Volba názvu zřizovacího profilu

  9. Po vytvoření nového zřizovacího profilu vyberte Stáhnout. Zapamatujte si umístění, do kterého se uloží.

  10. Přejděte do umístění zřizovacího profilu a poklikáním ho nainstalujte na vývojový počítač.

Vytvoření centra oznámení

V této části vytvoříte centrum oznámení a nakonfigurujete ověřování pomocí APNS. Můžete použít certifikát p12 push nebo ověřování založené na tokenech. Pokud chcete použít centrum oznámení, které jste už vytvořili, můžete přeskočit ke kroku 5.

  1. Přihlaste se k Azure.

  2. Klikněte na Vytvořit prostředek, vyhledejte a zvolte Centrum oznámení a pak klikněte na Vytvořit.

  3. Aktualizujte následující pole a pak klikněte na Vytvořit:

    ZÁKLADNÍ PODROBNOSTI

    Předplatné: V rozevíracím seznamu zvolte cílové předplatné.
    Skupina prostředků: Vytvoření nové skupiny prostředků (nebo výběr existující skupiny)

    PODROBNOSTI O OBORU NÁZVŮ

    Obor názvů centra oznámení: Zadejte globálně jedinečný název oboru názvů centra oznámení .

    Poznámka

    Ujistěte se, že je pro toto pole vybraná možnost Vytvořit nový .

    PODROBNOSTI CENTRA OZNÁMENÍ

    Centrum oznámení: Zadejte název centra oznámení.
    Umístění: V rozevíracím seznamu vyberte vhodné umístění.
    Cenová úroveň: Zachovat výchozí možnost Free

    Poznámka

    Pokud jste nedosáhli maximálního počtu center na úrovni Free.

  4. Po zřízení centra oznámení přejděte k ho prostředku.

  5. Přejděte do nového centra oznámení.

  6. V seznamu (v části SPRAVOVAT) vyberte Zásady přístupu.

  7. Poznamenejte si hodnoty Název zásady spolu s odpovídajícími hodnotami připojovacího řetězce .

Konfigurace centra oznámení s využitím informací APNS

V části Notification Services (Služby oznámení) vyberte Apple a pak postupujte podle postupu, který jste zvolili dříve v části Creating a Certificate for Notification Hubs (Vytvoření certifikátu pro Notification Hubs ).

Poznámka

Produkčnírežim pro aplikační režim používejte jenom v případě, že chcete odesílat nabízená oznámení uživatelům, kteří zakoupili vaši aplikaci z obchodu.

MOŽNOST 1: Použití nabízeného certifikátu .p12

  1. Vyberte Certifikát.

  2. Vyberte ikonu souboru.

  3. Vyberte soubor .p12, který jste vyexportovali dříve, a pak vyberte Otevřít.

  4. V případě potřeby zadejte správné heslo.

  5. Vyberte Režim sandboxu .

  6. Vyberte Uložit.

MOŽNOST 2: Použití ověřování na základě tokenů

  1. Vyberte Token.

  2. Zadejte následující hodnoty, které jste získali dříve:

    • ID klíče
    • ID sady
    • ID týmu
    • Token
  3. Zvolte Sandbox.

  4. Vyberte Uložit.

Konfigurace centra oznámení s využitím informací FCM

  1. V části Nastavení v nabídce vlevo vyberte Google (GCM/FCM).
  2. Zadejte klíč serveru , který jste si poznamenali z konzoly Google Firebase Console.
  3. Na panelu nástrojů vyberte Uložit .

Vytvoření back-endové aplikace ASP.NET Core webového rozhraní API

V této části vytvoříte back-end webového rozhraní API ASP.NET Core, který bude zpracovávat registraci zařízení a odesílání oznámení do mobilní aplikace Flutter.

Vytvoření webového projektu

  1. V sadě Visual Studio vyberte Soubor>nové řešení.

  2. VyberteAplikace>.NET Core>ASP.NET Core>Další rozhraní API>.

  3. V dialogovém okně Konfigurace nového webového rozhraní API ASP.NET Core vyberte Cílová architekturarozhraní .NET Core 3.1.

  4. Jako Název projektu zadejte PushDemoApi a pak vyberte Vytvořit.

  5. Spusťte ladění (příkaz Enter + ) a otestujte aplikaci v šabloně.

    Poznámka

    Aplikace v šabloně je nakonfigurovaná tak, aby jako launchUrl používala WeatherForecastController. Toto nastavení je nastaveno vlaunchSettings.jsonVlastnosti>.

    Pokud se zobrazí výzva se zprávou o nalezení neplatného vývojového certifikátu :

    1. Kliknutím na Ano potvrďte souhlas se spuštěním nástroje dotnet dev-certs https, který tento problém vyřeší. Nástroj dotnet dev-certs https vás pak vyzve k zadání hesla pro certifikát a hesla pro klíčku.

    2. Po zobrazení výzvy k instalaci a důvěryhodnosti nového certifikátu klikněte na Ano a pak zadejte heslo pro klíčku.

  6. Rozbalte složku Kontrolery a pak odstraňte WeatherForecastController.cs.

  7. Odstranit WeatherForecast.cs.

  8. Nastavte hodnoty místní konfigurace pomocí nástroje Secret Manager. Oddělení tajných kódů od řešení zajistí, že neskončí ve správě zdrojového kódu. Otevřete Terminál , přejděte do adresáře souboru projektu a spusťte následující příkazy:

    dotnet user-secrets init
    dotnet user-secrets set "NotificationHub:Name" <value>
    dotnet user-secrets set "NotificationHub:ConnectionString" <value>
    

    Zástupné hodnoty nahraďte vlastním názvem centra oznámení a hodnotami připojovací řetězec. Poznamenali jste si je v části Vytvoření centra oznámení . V opačném případě je můžete vyhledat v Azure.

    NotificationHub:Name:
    Název najdete v souhrnu Základy v horní části Přehled.

    NotificationHub:ConnectionString:
    Viz DefaultFullSharedAccessSignature v zásadách přístupu.

    Poznámka

    V produkčních scénářích se můžete podívat na možnosti bezpečného uložení připojovací řetězec, jako je Azure KeyVault. Pro zjednodušení se tajné kódy přidají do Azure App Service nastavení aplikace.

Ověřování klientů pomocí klíče rozhraní API (volitelné)

Klíče rozhraní API nejsou tak zabezpečené jako tokeny, ale pro účely tohoto kurzu budou stačit. Klíč rozhraní API je možné snadno nakonfigurovat prostřednictvím middlewaru ASP.NET.

  1. Přidejte klíč rozhraní API k hodnotám místní konfigurace.

    dotnet user-secrets set "Authentication:ApiKey" <value>
    

    Poznámka

    Zástupnou hodnotu byste měli nahradit vlastní hodnotou a poznamenejte si ji.

  2. Ovládací prvek + Klikněte na projekt PushDemoApi, v nabídce Přidat zvolte Nová složka a pak jako název složky klikněte na Přidat pomocí ověřování.

  3. Ovládací prvek + Klikněte na složku Ověřování a pak v nabídce Přidat zvolte Nový soubor.

  4. Vyberte Obecná>prázdná třída, jako Název zadejte ApiKeyAuthOptions.cs a pak klikněte na Nová a přidejte následující implementaci.

    using Microsoft.AspNetCore.Authentication;
    
    namespace PushDemoApi.Authentication
    {
        public class ApiKeyAuthOptions : AuthenticationSchemeOptions
        {
            public const string DefaultScheme = "ApiKey";
            public string Scheme => DefaultScheme;
            public string ApiKey { get; set; }
        }
    }
    
  5. Přidejte další prázdnou třídu do složky Ověřovánís názvem ApiKeyAuthHandler.cs a pak přidejte následující implementaci.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Claims;
    using System.Text.Encodings.Web;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authentication;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    
    namespace PushDemoApi.Authentication
    {
        public class ApiKeyAuthHandler : AuthenticationHandler<ApiKeyAuthOptions>
        {
            const string ApiKeyIdentifier = "apikey";
    
            public ApiKeyAuthHandler(
                IOptionsMonitor<ApiKeyAuthOptions> options,
                ILoggerFactory logger,
                UrlEncoder encoder,
                ISystemClock clock)
                : base(options, logger, encoder, clock) {}
    
            protected override Task<AuthenticateResult> HandleAuthenticateAsync()
            {
                string key = string.Empty;
    
                if (Request.Headers[ApiKeyIdentifier].Any())
                {
                    key = Request.Headers[ApiKeyIdentifier].FirstOrDefault();
                }
                else if (Request.Query.ContainsKey(ApiKeyIdentifier))
                {
                    if (Request.Query.TryGetValue(ApiKeyIdentifier, out var queryKey))
                        key = queryKey;
                }
    
                if (string.IsNullOrWhiteSpace(key))
                    return Task.FromResult(AuthenticateResult.Fail("No api key provided"));
    
                if (!string.Equals(key, Options.ApiKey, StringComparison.Ordinal))
                    return Task.FromResult(AuthenticateResult.Fail("Invalid api key."));
    
                var identities = new List<ClaimsIdentity> {
                    new ClaimsIdentity("ApiKeyIdentity")
                };
    
                var ticket = new AuthenticationTicket(
                    new ClaimsPrincipal(identities), Options.Scheme);
    
                return Task.FromResult(AuthenticateResult.Success(ticket));
            }
        }
    }
    

    Poznámka

    Obslužná rutina ověřování je typ, který implementuje chování schématu, v tomto případě vlastní schéma klíče rozhraní API.

  6. Do složky Authentication přidejte další prázdnou třídus názvem ApiKeyAuthenticationBuilderExtensions.cs a pak přidejte následující implementaci.

    using System;
    using Microsoft.AspNetCore.Authentication;
    
    namespace PushDemoApi.Authentication
    {
        public static class AuthenticationBuilderExtensions
        {
            public static AuthenticationBuilder AddApiKeyAuth(
                this AuthenticationBuilder builder,
                Action<ApiKeyAuthOptions> configureOptions)
            {
                return builder
                    .AddScheme<ApiKeyAuthOptions, ApiKeyAuthHandler>(
                        ApiKeyAuthOptions.DefaultScheme,
                        configureOptions);
            }
        }
    }
    

    Poznámka

    Tato rozšiřující metoda zjednodušuje konfigurační kód middlewaru v Startup.cs díky tomu je čitelnější a obecně jednodušší.

  7. V Startup.cs aktualizujte metodu ConfigureServices a nakonfigurujte ověřování pomocí klíče rozhraní API pod voláním služeb. Metoda AddControllers

    using PushDemoApi.Authentication;
    using PushDemoApi.Models;
    using PushDemoApi.Services;
    
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
    
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = ApiKeyAuthOptions.DefaultScheme;
            options.DefaultChallengeScheme = ApiKeyAuthOptions.DefaultScheme;
        }).AddApiKeyAuth(Configuration.GetSection("Authentication").Bind);
    }
    
  8. Stále v Startup.csaktualizujte metodu Configure tak, aby volala rozšiřující metody UseAuthentication a UseAuthorization v IApplicationBuilderu aplikace. Ujistěte se, že se tyto metody volají po PoužitíRouting a před aplikací. Použijte Koncové body.

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
    
        app.UseHttpsRedirection();
    
        app.UseRouting();
    
        app.UseAuthentication();
    
        app.UseAuthorization();
    
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
    

    Poznámka

    Volání metody UseAuthentication zaregistruje middleware, který používá dříve zaregistrovaná schémata ověřování (v části ConfigureServices). Toto nastavení se musí volat před jakýmkoli middlewarem, který závisí na ověřovaných uživatelích.

Přidání závislostí a konfigurace služeb

ASP.NET Core podporuje vzor návrhu softwaru pro injektáž závislostí (DI), což je technika pro dosažení inverze řízení (IoC) mezi třídami a jejich závislostmi.

Použití centra oznámení a sady Notification Hubs SDK pro back-endové operace je zapouzdřeno v rámci služby. Služba se zaregistruje a zpřístupní prostřednictvím vhodné abstrakce.

  1. Ovládací prvek + Klikněte na složku Dependencies (Závislosti ) a pak zvolte Manage NuGet Packages(Spravovat balíčky NuGet...).

  2. Vyhledejte Microsoft.Azure.NotificationHubs a ujistěte se, že je zaškrtnuté.

  3. Klikněte na Přidat balíčky a po zobrazení výzvy k přijetí licenčních podmínek klikněte na Přijmout .

  4. Ovládací prvek + Klikněte na projekt PushDemoApi, v nabídce Přidat zvolte Nová složka a pak jako název složky klikněte na Přidat pomocí modelů.

  5. Ovládací prvek + Klikněte na složku Models (Modely) a pak v nabídce Add (Přidat) zvolte New File... (Nový soubor).

  6. Vyberte Obecná>prázdná třída, jako Název zadejte PushTemplates.cs a pak klikněte na Nová a přidejte následující implementaci.

    namespace PushDemoApi.Models
    {
        public class PushTemplates
        {
            public class Generic
            {
                public const string Android = "{ \"notification\": { \"title\" : \"PushDemo\", \"body\" : \"$(alertMessage)\"}, \"data\" : { \"action\" : \"$(alertAction)\" } }";
                public const string iOS = "{ \"aps\" : {\"alert\" : \"$(alertMessage)\"}, \"action\" : \"$(alertAction)\" }";
            }
    
            public class Silent
            {
                public const string Android = "{ \"data\" : {\"message\" : \"$(alertMessage)\", \"action\" : \"$(alertAction)\"} }";
                public const string iOS = "{ \"aps\" : {\"content-available\" : 1, \"apns-priority\": 5, \"sound\" : \"\", \"badge\" : 0}, \"message\" : \"$(alertMessage)\", \"action\" : \"$(alertAction)\" }";
            }
        }
    }
    

    Poznámka

    Tato třída obsahuje tokenizované datové části oznámení pro obecná a bezobslužná oznámení vyžadovaná tímto scénářem. Datové části se definují mimo instalaci , aby bylo možné experimentovat bez nutnosti aktualizovat stávající instalace prostřednictvím služby. Zpracování změn v instalacích tímto způsobem je v tomto kurzu mimo rozsah. V produkčním prostředí zvažte vlastní šablony.

  7. Do složky Models přidejte další prázdnou třídus názvem DeviceInstallation.cs a pak přidejte následující implementaci.

    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace PushDemoApi.Models
    {
        public class DeviceInstallation
        {
            [Required]
            public string InstallationId { get; set; }
    
            [Required]
            public string Platform { get; set; }
    
            [Required]
            public string PushChannel { get; set; }
    
            public IList<string> Tags { get; set; } = Array.Empty<string>();
        }
    }
    
  8. Do složky Models přidejte další prázdnou třídus názvem NotificationRequest.cs a pak přidejte následující implementaci.

    using System;
    
    namespace PushDemoApi.Models
    {
        public class NotificationRequest
        {
            public string Text { get; set; }
            public string Action { get; set; }
            public string[] Tags { get; set; } = Array.Empty<string>();
            public bool Silent { get; set; }
        }
    }
    
  9. Do složky Models přidejte další prázdnou třídus názvem NotificationHubOptions.cs a pak přidejte následující implementaci.

    using System.ComponentModel.DataAnnotations;
    
    namespace PushDemoApi.Models
    {
        public class NotificationHubOptions
        {
            [Required]
            public string Name { get; set; }
    
            [Required]
            public string ConnectionString { get; set; }
        }
    }
    
  10. Do projektu PushDemoApi přidejte novou složku s názvem Services.

  11. Přidejte prázdné rozhraní do složky Services s názvem INotificationService.cs a pak přidejte následující implementaci.

    using System.Threading;
    using System.Threading.Tasks;
    using PushDemoApi.Models;
    
    namespace PushDemoApi.Services
    {
        public interface INotificationService
        {
            Task<bool> CreateOrUpdateInstallationAsync(DeviceInstallation deviceInstallation, CancellationToken token);
            Task<bool> DeleteInstallationByIdAsync(string installationId, CancellationToken token);
            Task<bool> RequestNotificationAsync(NotificationRequest notificationRequest, CancellationToken token);
        }
    }
    
  12. Přidejte prázdnou třídu do složky Services s názvem NotificationHubsService.cs a pak přidejte následující kód pro implementaci rozhraní INotificationService :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Azure.NotificationHubs;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    using PushDemoApi.Models;
    
    namespace PushDemoApi.Services
    {
        public class NotificationHubService : INotificationService
        {
            readonly NotificationHubClient _hub;
            readonly Dictionary<string, NotificationPlatform> _installationPlatform;
            readonly ILogger<NotificationHubService> _logger;
    
            public NotificationHubService(IOptions<NotificationHubOptions> options, ILogger<NotificationHubService> logger)
            {
                _logger = logger;
                _hub = NotificationHubClient.CreateClientFromConnectionString(
                    options.Value.ConnectionString,
                    options.Value.Name);
    
                _installationPlatform = new Dictionary<string, NotificationPlatform>
                {
                    { nameof(NotificationPlatform.Apns).ToLower(), NotificationPlatform.Apns },
                    { nameof(NotificationPlatform.Fcm).ToLower(), NotificationPlatform.Fcm }
                };
            }
    
            public async Task<bool> CreateOrUpdateInstallationAsync(DeviceInstallation deviceInstallation, CancellationToken token)
            {
                if (string.IsNullOrWhiteSpace(deviceInstallation?.InstallationId) ||
                    string.IsNullOrWhiteSpace(deviceInstallation?.Platform) ||
                    string.IsNullOrWhiteSpace(deviceInstallation?.PushChannel))
                    return false;
    
                var installation = new Installation()
                {
                    InstallationId = deviceInstallation.InstallationId,
                    PushChannel = deviceInstallation.PushChannel,
                    Tags = deviceInstallation.Tags
                };
    
                if (_installationPlatform.TryGetValue(deviceInstallation.Platform, out var platform))
                    installation.Platform = platform;
                else
                    return false;
    
                try
                {
                    await _hub.CreateOrUpdateInstallationAsync(installation, token);
                }
                catch
                {
                    return false;
                }
    
                return true;
            }
    
            public async Task<bool> DeleteInstallationByIdAsync(string installationId, CancellationToken token)
            {
                if (string.IsNullOrWhiteSpace(installationId))
                    return false;
    
                try
                {
                    await _hub.DeleteInstallationAsync(installationId, token);
                }
                catch
                {
                    return false;
                }
    
                return true;
            }
    
            public async Task<bool> RequestNotificationAsync(NotificationRequest notificationRequest, CancellationToken token)
            {
                if ((notificationRequest.Silent &&
                    string.IsNullOrWhiteSpace(notificationRequest?.Action)) ||
                    (!notificationRequest.Silent &&
                    (string.IsNullOrWhiteSpace(notificationRequest?.Text)) ||
                    string.IsNullOrWhiteSpace(notificationRequest?.Action)))
                    return false;
    
                var androidPushTemplate = notificationRequest.Silent ?
                    PushTemplates.Silent.Android :
                    PushTemplates.Generic.Android;
    
                var iOSPushTemplate = notificationRequest.Silent ?
                    PushTemplates.Silent.iOS :
                    PushTemplates.Generic.iOS;
    
                var androidPayload = PrepareNotificationPayload(
                    androidPushTemplate,
                    notificationRequest.Text,
                    notificationRequest.Action);
    
                var iOSPayload = PrepareNotificationPayload(
                    iOSPushTemplate,
                    notificationRequest.Text,
                    notificationRequest.Action);
    
                try
                {
                    if (notificationRequest.Tags.Length == 0)
                    {
                        // This will broadcast to all users registered in the notification hub
                        await SendPlatformNotificationsAsync(androidPayload, iOSPayload, token);
                    }
                    else if (notificationRequest.Tags.Length <= 20)
                    {
                        await SendPlatformNotificationsAsync(androidPayload, iOSPayload, notificationRequest.Tags, token);
                    }
                    else
                    {
                        var notificationTasks = notificationRequest.Tags
                            .Select((value, index) => (value, index))
                            .GroupBy(g => g.index / 20, i => i.value)
                            .Select(tags => SendPlatformNotificationsAsync(androidPayload, iOSPayload, tags, token));
    
                        await Task.WhenAll(notificationTasks);
                    }
    
                    return true;
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "Unexpected error sending notification");
                    return false;
                }
            }
    
            string PrepareNotificationPayload(string template, string text, string action) => template
                .Replace("$(alertMessage)", text, StringComparison.InvariantCulture)
                .Replace("$(alertAction)", action, StringComparison.InvariantCulture);
    
            Task SendPlatformNotificationsAsync(string androidPayload, string iOSPayload, CancellationToken token)
            {
                var sendTasks = new Task[]
                {
                    _hub.SendFcmNativeNotificationAsync(androidPayload, token),
                    _hub.SendAppleNativeNotificationAsync(iOSPayload, token)
                };
    
                return Task.WhenAll(sendTasks);
            }
    
            Task SendPlatformNotificationsAsync(string androidPayload, string iOSPayload, IEnumerable<string> tags, CancellationToken token)
            {
                var sendTasks = new Task[]
                {
                    _hub.SendFcmNativeNotificationAsync(androidPayload, tags, token),
                    _hub.SendAppleNativeNotificationAsync(iOSPayload, tags, token)
                };
    
                return Task.WhenAll(sendTasks);
            }
        }
    }
    

    Poznámka

    Výraz značky poskytnutý sendTemplateNotificationAsync je omezený na 20 značek. U většiny operátorů je omezený na 6, ale výraz v tomto případě obsahuje jenom operační prostředí (||). Pokud požadavek obsahuje více než 20 značek, musí být rozdělené do několika požadavků. Další podrobnosti najdete v dokumentaci ke směrování a výrazům značek .

  13. V Startup.cs aktualizujte metodu ConfigureServices , aby se služba NotificationHubsService přidala jako jednotná implementace služby INotificationService.

    
    using PushDemoApi.Models;
    using PushDemoApi.Services;
    
    public void ConfigureServices(IServiceCollection services)
    {
        ...
    
        services.AddSingleton<INotificationService, NotificationHubService>();
    
        services.AddOptions<NotificationHubOptions>()
            .Configure(Configuration.GetSection("NotificationHub").Bind)
            .ValidateDataAnnotations();
    }
    

Vytvoření rozhraní API pro oznámení

  1. Ovládací prvek + Klikněte na složku Kontrolery a pak v nabídce Přidat zvolte Nový soubor.

  2. Vyberte ASP.NET Core>Třída kontroleru webového rozhraní API, jako Název zadejte NotificationsController a pak klikněte na Nový.

    Poznámka

    Pokud používáte Visual Studio 2019, zvolte šablonu Kontroler rozhraní API s akcemi čtení a zápisu .

  3. Na začátek souboru přidejte následující obory názvů.

    using System.ComponentModel.DataAnnotations;
    using System.Net;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using PushDemoApi.Models;
    using PushDemoApi.Services;
    
  4. Aktualizujte kontroler podle šablony tak, aby byl odvozen z ControllerBase a je opatřen atributem ApiController .

    [ApiController]
    [Route("api/[controller]")]
    public class NotificationsController : ControllerBase
    {
        // Templated methods here
    }
    

    Poznámka

    Základní třída Controller poskytuje podporu zobrazení, ale v tomto případě to není potřeba, a proto lze místo toho použít ControllerBase . Pokud používáte Visual Studio 2019, můžete tento krok přeskočit.

  5. Pokud jste se rozhodli dokončit část Ověřování klientů pomocí klíče rozhraní API , měli byste oznámeníController opatřit také atributem Authorize .

    [Authorize]
    
  6. Aktualizujte konstruktor tak, aby přijal zaregistrovanou instanci INotificationService jako argument a přiřaďte jej členu jen pro čtení.

    readonly INotificationService _notificationService;
    
    public NotificationsController(INotificationService notificationService)
    {
        _notificationService = notificationService;
    }
    
  7. V launchSettings.json (ve složce Properties ) změňte launchUrl z weatherforecast na api/notifications tak, aby odpovídaly adrese URL zadané v atributu RegistrationsControllerRoute .

  8. Spusťte ladění (command + Enter), abyste ověřili, že aplikace funguje s novým NotificationsController a vrací stav 401 Neautorizováno .

    Poznámka

    Visual Studio nemusí aplikaci automaticky spustit v prohlížeči. Od tohoto okamžiku budete rozhraní API testovat pomocí nástroje Postman .

  9. Na nové kartě Postman nastavte požadavek na GET. Zadejte adresu níže, zástupnou <adresu applicationUrl nahraďte https applicationUrl> v části Vlastnosti>launchSettings.json.

    <applicationUrl>/api/notifications
    

    Poznámka

    Adresa applicationUrl by měla být pro výchozí profil nastavená na hodnotu .https://localhost:5001 Pokud používáte službu IIS (výchozí nastavení v sadě Visual Studio 2019 ve Windows), měli byste místo toho použít adresu applicationUrl zadanou v položce iisSettings . Pokud je adresa nesprávná, obdržíte odpověď 404.

  10. Pokud jste se rozhodli dokončit část Ověřování klientů pomocí klíče rozhraní API , nezapomeňte nakonfigurovat hlavičky požadavku tak, aby obsahovaly hodnotu klíče rozhraní API .

    Klíč Hodnotu
    klíč rozhraní API <your_api_key>
  11. Klikněte na tlačítko Odeslat .

    Poznámka

    U nějakého obsahu JSON by se měl zobrazit stav 200 OK.

    Pokud se zobrazí upozornění na ověření certifikátu SSL, můžete v Nastavení vypnout nastavení Postmana pro ověření certifikátu SSL.

  12. Metody třídy podle šablony v NotificationsController.cs nahraďte následujícím kódem.

    [HttpPut]
    [Route("installations")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    [ProducesResponseType((int)HttpStatusCode.BadRequest)]
    [ProducesResponseType((int)HttpStatusCode.UnprocessableEntity)]
    public async Task<IActionResult> UpdateInstallation(
        [Required]DeviceInstallation deviceInstallation)
    {
        var success = await _notificationService
            .CreateOrUpdateInstallationAsync(deviceInstallation, HttpContext.RequestAborted);
    
        if (!success)
            return new UnprocessableEntityResult();
    
        return new OkResult();
    }
    
    [HttpDelete()]
    [Route("installations/{installationId}")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    [ProducesResponseType((int)HttpStatusCode.BadRequest)]
    [ProducesResponseType((int)HttpStatusCode.UnprocessableEntity)]
    public async Task<ActionResult> DeleteInstallation(
        [Required][FromRoute]string installationId)
    {
        var success = await _notificationService
            .DeleteInstallationByIdAsync(installationId, CancellationToken.None);
    
        if (!success)
            return new UnprocessableEntityResult();
    
        return new OkResult();
    }
    
    [HttpPost]
    [Route("requests")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    [ProducesResponseType((int)HttpStatusCode.BadRequest)]
    [ProducesResponseType((int)HttpStatusCode.UnprocessableEntity)]
    public async Task<IActionResult> RequestPush(
        [Required]NotificationRequest notificationRequest)
    {
        if ((notificationRequest.Silent &&
            string.IsNullOrWhiteSpace(notificationRequest?.Action)) ||
            (!notificationRequest.Silent &&
            string.IsNullOrWhiteSpace(notificationRequest?.Text)))
            return new BadRequestResult();
    
        var success = await _notificationService
            .RequestNotificationAsync(notificationRequest, HttpContext.RequestAborted);
    
        if (!success)
            return new UnprocessableEntityResult();
    
        return new OkResult();
    }
    

Vytvoření aplikace API

Teď v Azure App Service vytvoříte aplikaci API pro hostování back-endové služby.

  1. Přihlaste se k Azure Portal.

  2. Klikněte na Vytvořit prostředek, vyhledejte, zvolte Aplikace API a pak klikněte na Vytvořit.

  3. Aktualizujte následující pole a klikněte na Vytvořit.

    Název aplikace:
    Zadejte globálně jedinečný název aplikace API.

    Předplatné:
    Zvolte stejné cílové předplatné, ve které jste vytvořili centrum oznámení.

    Skupina prostředků:
    Zvolte stejnou skupinu prostředků , ve které jste vytvořili centrum oznámení.

    App Service plán/umístění:
    Vytvoření nového plánu App Service

    Poznámka

    Přejděte z výchozí možnosti na plán, který zahrnuje podporu SSL . Jinak budete muset při práci s mobilní aplikací provést příslušné kroky, abyste zabránili blokování požadavků HTTP .

    Application Insights:
    Ponechte si navrhovanou možnost (nový prostředek se vytvoří pod tímto názvem) nebo vyberte existující prostředek.

  4. Po zřízení aplikace API přejděte k ho prostředku.

  5. Poznamenejte si vlastnost URL v souhrnu Základy v horní části přehledu. Tato adresa URL je váš koncový bod back-endu , který použijeme později v tomto kurzu.

    Poznámka

    Adresa URL používá název aplikace API, který jste zadali dříve, ve formátu https://<app_name>.azurewebsites.net.

  6. V seznamu (v části Nastavení) vyberte Konfigurace.

  7. Pro každé z níže uvedených nastavení klikněte na Nové nastavení aplikace a zadejte Název a Hodnotu a pak klikněte na OK.

    Jméno Hodnotu
    Authentication:ApiKey <api_key_value>
    NotificationHub:Name <hub_name_value>
    NotificationHub:ConnectionString <hub_connection_string_value>

    Poznámka

    Jedná se o stejná nastavení, která jste definovali dříve v uživatelských nastaveních. Měli byste být schopni je zkopírovat. Nastavení Authentication:ApiKey je povinné jenom v případě, že jste se rozhodli dokončit část Ověřování klientů pomocí klíče rozhraní API . V produkčních scénářích se můžete podívat na možnosti, jako je Azure KeyVault. Ty byly v tomto případě přidány jako nastavení aplikace pro zjednodušení.

  8. Po přidání všech nastavení aplikace klikněte na Uložit a pak na Pokračovat.

Publikování back-endové služby

Dále aplikaci nasadíte do aplikace API, aby byla přístupná ze všech zařízení.

Poznámka

Následující kroky jsou specifické pro Visual Studio pro Mac. Pokud používáte Visual Studio 2019 ve Windows, tok publikování se bude lišit. Viz Publikování do Azure App Service ve Windows.

  1. Pokud jste to ještě neudělali, změňte konfiguraci z Ladění na Vydání .

  2. Ovládací prvek + Klikněte na projekt PushDemoApi a pak v nabídce Publish (Publikovat) zvolte Publish to Azure... (Publikovat do Azure... ).

  3. Pokud se zobrazí výzva, postupujte podle toku ověřování. Použijte účet, který jste použili při předchozím vytvoření oddílu aplikace API .

  4. Jako cíl publikování vyberte aplikaci api Azure App Service, kterou jste vytvořili dříve, a pak klikněte na Publikovat.

Po dokončení průvodce publikuje aplikaci do Azure a otevře ji. Poznamenejte si adresu URL , pokud jste to ještě neudělali. Tato adresa URL je váš back-endový koncový bod , který se použije později v tomto kurzu.

Ověření publikovaného rozhraní API

  1. V nástroji Postman otevřete novou kartu, nastavte požadavek na PUT a zadejte níže uvedenou adresu. Zástupný symbol nahraďte základní adresou, kterou jste si poznamenali v předchozím oddílu publikování back-endové služby .

    https://<app_name>.azurewebsites.net/api/notifications/installations
    

    Poznámka

    Základní adresa by měla být ve formátu . https://<app_name>.azurewebsites.net/

  2. Pokud jste se rozhodli dokončit část Ověřování klientů pomocí klíče rozhraní API , nezapomeňte nakonfigurovat hlavičky požadavku tak, aby obsahovaly hodnotu klíče rozhraní API .

    Klíč Hodnotu
    klíč rozhraní API <your_api_key>
  3. Zvolte nezpracovanou možnost pro text, pak v seznamu možností formátování zvolte JSON a pak přidejte nějaký zástupný obsah JSON :

    {}
    
  4. Klikněte na Odeslat.

    Poznámka

    Ze služby byste měli obdržet stav 422 UnprocessableEntity .

  5. Znovu proveďte kroky 1 až 4, ale tentokrát zadejte koncový bod požadavků, abyste ověřili, že obdržíte odpověď 400 – Chybný požadavek .

    https://<app_name>.azurewebsites.net/api/notifications/requests
    

Poznámka

Rozhraní API zatím není možné otestovat pomocí platných dat požadavků, protože to bude vyžadovat informace specifické pro platformu z klientské mobilní aplikace.

Vytvoření multiplatformní aplikace Flutter

V této části vytvoříte mobilní aplikaci Flutter , která implementuje nabízená oznámení pro různé platformy.

Umožňuje registraci a zrušení registrace z centra oznámení prostřednictvím back-endové služby, kterou jste vytvořili.

Upozornění se zobrazí, když je zadaná akce a aplikace je v popředí. V opačném případě se oznámení zobrazí v centru oznámení.

Poznámka

Akce registrace (a zrušení registrace) byste obvykle prováděli v příslušném bodě životního cyklu aplikace (nebo možná jako součást prvního spuštění) bez explicitních vstupů registrace/zrušení registrace uživatele. Tento příklad ale bude vyžadovat explicitní uživatelský vstup, aby bylo možné tuto funkci snadněji prozkoumat a otestovat.

Vytvoření řešení Flutter

  1. Otevřete novou instanci editoru Visual Studio Code.

  2. Otevřete paletu příkazů (Shift + Command + P).

  3. Vyberte příkaz Flutter: New Project (Flutter: Nový projekt ) a stiskněte Enter.

  4. Jako Název projektu zadejte push_demo a pak vyberte umístění projektu.

  5. Po zobrazení výzvy zvolte Získat balíčky.

  6. Ovládací prvek + Klikněte na složku kotlin (v části app>src>main) a pak zvolte Zobrazit ve Finderu. Potom přejmenujte podřízené složky (ve složce kotlin ) na com, <your_organization>a pushdemo v uvedeném pořadí.

    Poznámka

    Při použití šablony editoru Visual Studio Code se tyto složky ve výchozím nastavení používají jako com, <například project_name>. Za předpokladu, že se pro organizaci používá mobcat, měla by struktura složek předběžně vypadat takto:

    • kotlin
      • Modelu com
        • mobcat
          • pushdemo
  7. Zpět v editoru Visual Studio Code aktualizujte hodnotu applicationId v souborubuild.gradleaplikace>pro Android> na com.<your_organization>.pushdemo.

    Poznámka

    Jako zástupný symbol your_organization> byste měli použít vlastní název< organizace. Například použití mobcat jako organizace bude mít za následek hodnotu názvu balíčkucom.mobcat.pushdemo.

  8. Aktualizujte atribut package v souborechAndroidManifest.xml v rámciprofilusrc>debug, src>main a src>. Ujistěte se, že hodnoty odpovídají hodnotě applicationId , kterou jste použili v předchozím kroku.

    <manifest
        xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.<your_organization>.pushdemo>">
        ...
    </manifest>
    
  9. android:label Aktualizujte atribut v souboruAndroidManifest.xml v části src>main na PushDemo. Pak přidejte android:allowBackup atribut přímo do pole android:labela nastavte jeho hodnotu na false.

    <application
        android:name="io.flutter.app.FlutterApplication"
        android:label="PushDemo"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher">
        ...
    </application>
    
  10. Otevřete soubor build.gradle na úrovni aplikace (build.gradleaplikace> pro Android>) a pak aktualizujte compileSdkVersion (z části android) tak, aby používal rozhraní API 29. Potom aktualizujte hodnoty minSdkVersion a targetSdkVersion (v části defaultConfig ) na 26 a 29 .

    Poznámka

    Pro účely tohoto kurzu jsou podporována pouze zařízení s rozhraním API úrovně 26 a vyšší , ale můžete ho rozšířit o zařízení se staršími verzemi.

  11. Ovládací prvek + Klikněte na složku ios a pak zvolte Otevřít v Xcode.

  12. V Xcode klikněte na Runner ( xcodeproj v horní části, ne na složku). Pak vyberte cíl Runneru a vyberte kartu Obecné . S vybranou konfigurací sestavení All (Vše ) aktualizujte identifikátor sady nacom.<your_organization>.PushDemo.

    Poznámka

    Jako zástupný symbol your_organization> byste měli použít vlastní název< organizace. Například použití mobcat jako organizace bude mít za následek hodnotu Bundle Identifiercom.mobcat.PushDemo.

  13. Klikněte na Info.plist a pak aktualizujte hodnotu Název sady na PushDemo.

  14. Zavřete Xcode a vraťte se do editoru Visual Studio Code.

  15. Zpět v editoru Visual Studio Code otevřete soubor pubspec.yaml, přidejte http a flutter_secure_storagebalíčky Dart jako závislosti. Potom soubor uložte a po zobrazení výzvy klikněte na Získat balíčky .

    dependencies:
      flutter:
        sdk: flutter
    
      http: ^0.12.1
      flutter_secure_storage: ^3.3.3
    
  16. V terminálu změňte adresář na složku ios (pro váš projekt Flutter). Potom spusťte příkaz pro instalaci podu , který nainstaluje nové pody (vyžadované balíčkem flutter_secure_storage ).

  17. Ovládací prvek + Klikněte na složku lib a pak v nabídce zvolte Nový soubor a jako název souboru použijte main_page.dart . Pak přidejte následující kód.

    import 'package:flutter/material.dart';
    
    class MainPage extends StatefulWidget {
      @override
      _MainPageState createState() => _MainPageState();
    }
    
    class _MainPageState extends State<MainPage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: SafeArea(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[],
            )
          )
        );
      }
    }
    
  18. V souboru main.dart nahraďte kód podle šablony následujícím kódem.

    import 'package:flutter/material.dart';
    import 'package:push_demo/main_page.dart';
    
    final navigatorKey = GlobalKey<NavigatorState>();
    
    void main() => runApp(MaterialApp(home: MainPage(), navigatorKey: navigatorKey));
    
  19. V terminálu sestavte a spusťte aplikaci na každé cílové platformě a otestujte, že aplikace v šabloně běží na vašich zařízeních. Ujistěte se, že jsou připojená podporovaná zařízení.

    flutter run
    

Implementace komponent pro různé platformy

  1. Ovládací prvek + Klikněte na složku lib a pak v nabídce zvolte Nová složka a jako Název složky použijte models.

  2. Ovládací prvek + Klikněte na složku models a pak v nabídce zvolte Nový soubor a jako název souboru použijte device_installation.dart . Pak přidejte následující kód.

    class DeviceInstallation {
        final String deviceId;
        final String platform;
        final String token;
        final List<String> tags;
    
        DeviceInstallation(this.deviceId, this.platform, this.token, this.tags);
    
        DeviceInstallation.fromJson(Map<String, dynamic> json)
          : deviceId = json['installationId'],
            platform = json['platform'],
            token = json['pushChannel'],
            tags = json['tags'];
    
        Map<String, dynamic> toJson() =>
        {
          'installationId': deviceId,
          'platform': platform,
          'pushChannel': token,
          'tags': tags,
        };
    }
    
  3. Do složky models přidejte nový soubor s názvem push_demo_action.dart definující výčet akcí podporovaných v tomto příkladu.

    enum PushDemoAction {
      actionA,
      actionB,
    }
    
  4. Přidejte do projektu novou složku s názvem services a pak do této složky přidejte nový soubor s názvem device_installation_service.dart s následující implementací.

    import 'package:flutter/services.dart';
    
    class DeviceInstallationService {
      static const deviceInstallation = const MethodChannel('com.<your_organization>.pushdemo/deviceinstallation');
      static const String getDeviceIdChannelMethod = "getDeviceId";
      static const String getDeviceTokenChannelMethod = "getDeviceToken";
      static const String getDevicePlatformChannelMethod = "getDevicePlatform";
    
      Future<String> getDeviceId() {
        return deviceInstallation.invokeMethod(getDeviceIdChannelMethod);
      }
    
      Future<String> getDeviceToken() {
        return deviceInstallation.invokeMethod(getDeviceTokenChannelMethod);
      }
    
      Future<String> getDevicePlatform() {
        return deviceInstallation.invokeMethod(getDevicePlatformChannelMethod);
      }
    }
    

    Poznámka

    Jako zástupný symbol your_organization> byste měli použít vlastní název< organizace. Například použití mobcat jako organizace bude mít za následek methodChannel název com.mobcat.pushdemo/deviceinstallation.

    Tato třída zapouzdřuje práci se základní nativní platformou za účelem získání požadovaných podrobností o instalaci zařízení. MethodChannel umožňuje obousměrnou asynchronní komunikaci se základními nativními platformami. Protějšek pro konkrétní platformu pro tento kanál se vytvoří v pozdějších krocích.

  5. Přidejte do této složky další soubor s názvem notification_action_service.dart s následující implementací.

    import 'package:flutter/services.dart';
    import 'dart:async';
    import 'package:push_demo/models/push_demo_action.dart';
    
    class NotificationActionService {
      static const notificationAction =
          const MethodChannel('com.<your_organization>.pushdemo/notificationaction');
      static const String triggerActionChannelMethod = "triggerAction";
      static const String getLaunchActionChannelMethod = "getLaunchAction";
    
      final actionMappings = {
        'action_a' : PushDemoAction.actionA,
        'action_b' : PushDemoAction.actionB
      };
    
      final actionTriggeredController = StreamController.broadcast();
    
      NotificationActionService() {
        notificationAction
            .setMethodCallHandler(handleNotificationActionCall);
      }
    
      Stream get actionTriggered => actionTriggeredController.stream;
    
      Future<void> triggerAction({action: String}) async {
    
        if (!actionMappings.containsKey(action)) {
          return;
        }
    
        actionTriggeredController.add(actionMappings[action]);
      }
    
      Future<void> checkLaunchAction() async {
        final launchAction = await notificationAction.invokeMethod(getLaunchActionChannelMethod) as String;
    
        if (launchAction != null) {
          triggerAction(action: launchAction);
        }
      }
    
      Future<void> handleNotificationActionCall(MethodCall call) async {
        switch (call.method) {
          case triggerActionChannelMethod:
            return triggerAction(action: call.arguments as String);
          default:
            throw MissingPluginException();
            break;
        }
      }
    }
    

    Poznámka

    Používá se jako jednoduchý mechanismus pro centralizaci zpracování akcí oznámení, aby bylo možné je zpracovat multiplatformně pomocí výčtu silného typu. Služba umožňuje základní nativní platformě aktivovat akci, pokud je zadaná v datové části oznámení. Umožňuje také společnému kódu zpětně zkontrolovat, jestli byla při spuštění aplikace zadána akce, jakmile flutter je připraven ji zpracovat. Například když se aplikace spustí klepnutím na oznámení z centra oznámení.

  6. Přidejte nový soubor do složky servicess názvem notification_registration_service.dart s následující implementací.

    import 'dart:convert';
    import 'package:flutter/services.dart';
    import 'package:http/http.dart' as http;
    import 'package:push_demo/services/device_installation_service.dart';
    import 'package:push_demo/models/device_installation.dart';
    import 'package:flutter_secure_storage/flutter_secure_storage.dart';
    
    class NotificationRegistrationService {
      static const notificationRegistration =
          const MethodChannel('com.<your_organization>.pushdemo/notificationregistration');
    
      static const String refreshRegistrationChannelMethod = "refreshRegistration";
      static const String installationsEndpoint = "api/notifications/installations";
      static const String cachedDeviceTokenKey = "cached_device_token";
      static const String cachedTagsKey = "cached_tags";
    
      final deviceInstallationService = DeviceInstallationService();
      final secureStorage = FlutterSecureStorage();
    
      String baseApiUrl;
      String apikey;
    
      NotificationRegistrationService(this.baseApiUrl, this.apikey) {
        notificationRegistration
            .setMethodCallHandler(handleNotificationRegistrationCall);
      }
    
      String get installationsUrl => "$baseApiUrl$installationsEndpoint";
    
      Future<void> deregisterDevice() async {
        final cachedToken = await secureStorage.read(key: cachedDeviceTokenKey);
        final serializedTags = await secureStorage.read(key: cachedTagsKey);
    
        if (cachedToken == null || serializedTags == null) {
          return;
        }
    
        var deviceId = await deviceInstallationService.getDeviceId();
    
        if (deviceId.isEmpty) {
          throw "Unable to resolve an ID for the device.";
        }
    
        var response = await http
            .delete("$installationsUrl/$deviceId", headers: {"apikey": apikey});
    
        if (response.statusCode != 200) {
          throw "Deregister request failed: ${response.reasonPhrase}";
        }
    
        await secureStorage.delete(key: cachedDeviceTokenKey);
        await secureStorage.delete(key: cachedTagsKey);
      }
    
      Future<void> registerDevice(List<String> tags) async {
        try {
          final deviceId = await deviceInstallationService.getDeviceId();
          final platform = await deviceInstallationService.getDevicePlatform();
          final token = await deviceInstallationService.getDeviceToken();
    
          final deviceInstallation =
              DeviceInstallation(deviceId, platform, token, tags);
    
          final response = await http.put(installationsUrl,
              body: jsonEncode(deviceInstallation),
              headers: {"apikey": apikey, "Content-Type": "application/json"});
    
          if (response.statusCode != 200) {
            throw "Register request failed: ${response.reasonPhrase}";
          }
    
          final serializedTags = jsonEncode(tags);
    
          await secureStorage.write(key: cachedDeviceTokenKey, value: token);
          await secureStorage.write(key: cachedTagsKey, value: serializedTags);
        } on PlatformException catch (e) {
          throw e.message;
        } catch (e) {
          throw "Unable to register device: $e";
        }
      }
    
      Future<void> refreshRegistration() async {
        final currentToken = await deviceInstallationService.getDeviceToken();
        final cachedToken = await secureStorage.read(key: cachedDeviceTokenKey);
        final serializedTags = await secureStorage.read(key: cachedTagsKey);
    
        if (currentToken == null ||
            cachedToken == null ||
            serializedTags == null ||
            currentToken == cachedToken) {
          return;
        }
    
        final tags = jsonDecode(serializedTags);
    
        return registerDevice(tags);
      }
    
      Future<void> handleNotificationRegistrationCall(MethodCall call) async {
        switch (call.method) {
          case refreshRegistrationChannelMethod:
            return refreshRegistration();
          default:
            throw MissingPluginException();
            break;
        }
      }
    }
    

    Poznámka

    Tato třída zapouzdřuje použití služby DeviceInstallationService a požadavků na back-endovou službu k provedení požadovaných akcí registrace, zrušení registrace a aktualizace. Argument apiKey se vyžaduje jenom v případě, že jste se rozhodli dokončit část Ověřování klientů pomocí klíče rozhraní API .

  7. Přidejte nový soubor do složky knihovnys názvem config.dart s následující implementací.

    class Config {
      static String apiKey = "API_KEY";
      static String backendServiceEndpoint = "BACKEND_SERVICE_ENDPOINT";
    }
    

    Poznámka

    Používá se jako jednoduchý způsob definování tajných kódů aplikací. Zástupné hodnoty nahraďte vlastními. Měli jste si je poznamenat při vytváření back-endové služby. Adresa URL aplikace API by měla být https://<api_app_name>.azurewebsites.net/. Člen apiKey se vyžaduje pouze v případě, že jste se rozhodli dokončit část Ověřování klientů pomocí klíče rozhraní API .

    Nezapomeňte ho přidat do souboru gitignore, abyste se vyhnuli potvrzení těchto tajných kódů do správy zdrojového kódu.

Implementace uživatelského rozhraní pro různé platformy

  1. V souboru main_page.dart nahraďte funkci buildu následujícím kódem.

    @override
    Widget build(BuildContext context) {
    return Scaffold(
        body: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 40.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.end,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              FlatButton(
                child: Text("Register"),
                onPressed: registerButtonClicked,
              ),
              FlatButton(
                child: Text("Deregister"),
                onPressed: deregisterButtonClicked,
              ),
            ],
          ),
        ),
      );
    }
    
  2. Přidejte požadované importy na začátek souboru main_page.dart .

    import 'package:push_demo/services/notification_registration_service.dart';
    import 'config.dart';
    
  3. Do třídy _MainPageState přidejte pole pro uložení odkazu na NotificationRegistrationService.

    final notificationRegistrationService = NotificationRegistrationService(Config.backendServiceEndpoint, Config.apiKey);
    
  4. Ve třídě _MainPageState implementujte obslužné rutiny událostí pro tlačítka Zaregistrovat a Zrušit registraciu událostíPressed . Zavolejte odpovídající metody Register/Deregister a pak zobrazte výstrahu, která indikuje výsledek.

    void registerButtonClicked() async {
        try {
          await notificationRegistrationService.registerDevice(List<String>());
          await showAlert(message: "Device registered");
        }
        catch (e) {
          await showAlert(message: e);
        }
      }
    
      void deregisterButtonClicked() async {
        try {
          await notificationRegistrationService.deregisterDevice();
          await showAlert(message: "Device deregistered");
        }
        catch (e) {
          await showAlert(message: e);
        }
      }
    
      Future<void> showAlert({ message: String }) async {
        return showDialog<void>(
          context: context,
          barrierDismissible: false,
          builder: (BuildContext context) {
            return AlertDialog(
              title: Text('PushDemo'),
              content: SingleChildScrollView(
                child: ListBody(
                  children: <Widget>[
                    Text(message),
                  ],
                ),
              ),
              actions: <Widget>[
                FlatButton(
                  child: Text('OK'),
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                ),
              ],
            );
          },
        );
      }
    
  5. Teď v souboru main.dart zkontrolujte, že v horní části souboru jsou následující importy.

    import 'package:flutter/material.dart';
    import 'package:push_demo/models/push_demo_action.dart';
    import 'package:push_demo/services/notification_action_service.dart';
    import 'package:push_demo/main_page.dart';
    
  6. Deklarujte proměnnou pro uložení odkazu na instanci NotificationActionService a inicializujte ji.

    final notificationActionService = NotificationActionService();
    
  7. Přidání funkcí pro zpracování zobrazení upozornění při aktivaci akce

    void notificationActionTriggered(PushDemoAction action) {
      showActionAlert(message: "${action.toString().split(".")[1]} action received");
    }
    
    Future<void> showActionAlert({ message: String }) async {
      return showDialog<void>(
        context: navigatorKey.currentState.overlay.context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return AlertDialog(
            title: Text('PushDemo'),
            content: SingleChildScrollView(
              child: ListBody(
                children: <Widget>[
                  Text(message),
                ],
              ),
            ),
            actions: <Widget>[
              FlatButton(
                child: Text('OK'),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              ),
            ],
          );
        },
      );
    }
    
  8. Aktualizujte hlavní funkci tak, aby sledovala stream s akcí NotificationActionServiceTriggered, a zkontrolujte všechny akce zachycené při spuštění aplikace.

    void main() async {
      runApp(MaterialApp(home: MainPage(), navigatorKey: navigatorKey,));
      notificationActionService.actionTriggered.listen((event) { notificationActionTriggered(event as PushDemoAction); });
      await notificationActionService.checkLaunchAction();
    }
    

    Poznámka

    Slouží pouze k předvedení příjmu a šíření akcí nabízených oznámení. Ty se obvykle zpracovávají bezobslužně, například při přechodu do určitého zobrazení nebo při aktualizaci dat, místo aby se zobrazila výstraha.

Konfigurace nativního projektu androidu pro nabízená oznámení

Přidání souboru JSON služeb Google

  1. Ovládací prvek + Klikněte na složku Android a pak zvolte Otevřít v Android Studiu. Pak přepněte do zobrazení Project (pokud ještě není).

  2. Vyhledejte soubor google-services.json , který jste stáhli dříve při nastavování projektu PushDemo v konzole Firebase. Pak ho přetáhněte do kořenového adresáře modulu aplikace (aplikace proAndroid>>).

Konfigurace nastavení a oprávnění sestavení

  1. Přepněte zobrazení Projectu na Android.

  2. Otevřete AndroidManifest.xmla pak přidejte oprávnění k internetu a READ_PHONE_STATE za element aplikace před uzavírací značku.

    <manifest>
        <application>...</application>
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    </manifest>
    

Přidání sad Firebase SDK

  1. V Android Studiu otevřete soubor build.gradle na úrovni projektu (Gradle Scripts>build.gradle (Projekt: android)). a ujistěte se, že v buildscript> uzlu závislostí máte cestu ke třídě com.google.gms:google-services.

    buildscript {
    
      repositories {
        // Check that you have the following line (if not, add it):
        google()  // Google's Maven repository
      }
    
      dependencies {
        // ...
    
        // Add the following line:
        classpath 'com.google.gms:google-services:4.3.3'  // Google Services plugin
      }
    }
    
    allprojects {
      // ...
    
      repositories {
        // Check that you have the following line (if not, add it):
        google()  // Google's Maven repository
        // ...
      }
    }
    

    Poznámka

    Ujistěte se, že při vytváření projektu pro Android odkazujete na nejnovější verzi podle pokynů uvedených v konzole Firebase.

  2. V souboru build.gradle na úrovni aplikace (Gradle Scripts>build.gradle (modul: aplikace)) použijte modul plug-in Google Services Gradle. Použijte modul plug-in přímo nad uzlem Androidu .

    // ...
    
    // Add the following line:
    apply plugin: 'com.google.gms.google-services'  // Google Services plugin
    
    android {
      // ...
    }
    
  3. Do stejného souboru v uzlu dependencies přidejte závislost pro knihovnu Cloud Messaging pro Android.

    dependencies {
        // ...
        implementation 'com.google.firebase:firebase-messaging:20.2.0'
    }
    

    Poznámka

    Ujistěte se, že odkazujete na nejnovější verzi podle dokumentace ke klientovi Cloud Messaging pro Android.

  4. Uložte změny a klikněte na tlačítko Synchronizovat (na panelu nástrojů) nebo Synchronizovat projekt se soubory Gradle.

Zpracování nabízených oznámení pro Android

  1. V Nástroji Android Studio klikněte + control na složku balíčku com.your_organization.pushdemo<> (app>src>main>kotlin) a v nabídce Nový zvolte Balíček. Jako název zadejte services a stiskněte Return.

  2. Ovládací prvek + Klikněte na složku services a v nabídce Nový zvolte Kotlin Soubor nebo třída. Jako název zadejte DeviceInstallationService a stiskněte Return.

  3. Implementujte službu DeviceInstallationService pomocí následujícího kódu.

    package com.<your_organization>.pushdemo.services
    
    import android.annotation.SuppressLint
    import android.content.Context
    import android.provider.Settings.Secure
    import com.google.android.gms.common.ConnectionResult
    import com.google.android.gms.common.GoogleApiAvailability
    import io.flutter.embedding.engine.FlutterEngine
    import io.flutter.plugin.common.MethodCall
    import io.flutter.plugin.common.MethodChannel
    
    @SuppressLint("HardwareIds")
    class DeviceInstallationService {
    
        companion object {
            const val DEVICE_INSTALLATION_CHANNEL = "com.<your_organization>.pushdemo/deviceinstallation"
            const val GET_DEVICE_ID = "getDeviceId"
            const val GET_DEVICE_TOKEN = "getDeviceToken"
            const val GET_DEVICE_PLATFORM = "getDevicePlatform"
        }
    
        private var context: Context
        private var deviceInstallationChannel : MethodChannel
    
        val playServicesAvailable
            get() = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS
    
        constructor(context: Context, flutterEngine: FlutterEngine) {
            this.context = context
            deviceInstallationChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, DEVICE_INSTALLATION_CHANNEL)
            deviceInstallationChannel.setMethodCallHandler { call, result -> handleDeviceInstallationCall(call, result) }
        }
    
        fun getDeviceId() : String
            = Secure.getString(context.applicationContext.contentResolver, Secure.ANDROID_ID)
    
        fun getDeviceToken() : String {
            if(!playServicesAvailable) {
                throw Exception(getPlayServicesError())
            }
    
            // TODO: Revisit once we have created the PushNotificationsFirebaseMessagingService
            val token = "Placeholder_Get_Value_From_FirebaseMessagingService_Implementation"
    
            if (token.isNullOrBlank()) {
                throw Exception("Unable to resolve token for FCM.")
            }
    
            return token
        }
    
        fun getDevicePlatform() : String = "fcm"
    
        private fun handleDeviceInstallationCall(call: MethodCall, result: MethodChannel.Result) {
            when (call.method) {
                GET_DEVICE_ID -> {
                    result.success(getDeviceId())
                }
                GET_DEVICE_TOKEN -> {
                    getDeviceToken(result)
                }
                GET_DEVICE_PLATFORM -> {
                    result.success(getDevicePlatform())
                }
                else -> {
                    result.notImplemented()
                }
            }
        }
    
        private fun getDeviceToken(result: MethodChannel.Result) {
            try {
                val token = getDeviceToken()
                result.success(token)
            }
            catch (e: Exception) {
                result.error("ERROR", e.message, e)
            }
        }
    
        private fun getPlayServicesError(): String {
            val resultCode = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context)
    
            if (resultCode != ConnectionResult.SUCCESS) {
                return if (GoogleApiAvailability.getInstance().isUserResolvableError(resultCode)){
                    GoogleApiAvailability.getInstance().getErrorString(resultCode)
                } else {
                    "This device is not supported"
                }
            }
    
            return "An error occurred preventing the use of push notifications"
        }
    }
    

    Poznámka

    Tato třída implementuje pro kanál specifický pro platformu com.<your_organization>.pushdemo/deviceinstallation . To bylo definováno v části Flutter aplikace v deviceInstallationService.dart. V tomto případě se volání provádí ze společného kódu na nativního hostitele. Nezapomeňte your_organization> nahradit< vlastní organizací bez ohledu na to, kde se to používá.

    Tato třída poskytuje jedinečné ID (pomocí Secure.AndroidId) jako součást datové části registrace centra oznámení.

  4. Do složky služeb přidejte další soubor nebo třídu Kotlin s názvem NotificationRegistrationService a pak přidejte následující kód.

    package com.<your_organization>.pushdemo.services
    
    import io.flutter.embedding.engine.FlutterEngine
    import io.flutter.plugin.common.MethodChannel
    
    class NotificationRegistrationService {
    
        companion object {
            const val NOTIFICATION_REGISTRATION_CHANNEL = "com.<your_organization>.pushdemo/notificationregistration"
            const val REFRESH_REGISTRATION = "refreshRegistration"
        }
    
        private var notificationRegistrationChannel : MethodChannel
    
        constructor(flutterEngine: FlutterEngine) {
            notificationRegistrationChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, NotificationRegistrationService.NOTIFICATION_REGISTRATION_CHANNEL)
        }
    
        fun refreshRegistration() {
            notificationRegistrationChannel.invokeMethod(REFRESH_REGISTRATION, null)
        }
    }
    

    Poznámka

    Tato třída implementuje pro kanál specifický pro platformu com.<your_organization>.pushdemo/notificationregistration . To bylo definováno v části Flutter aplikace v části NotificationRegistrationService.dart. V tomto případě se volání provádí z nativního hostitele do společného kódu. Znovu dbejte na to, abyste your_organization> nahradili< vlastní organizací bez ohledu na to, kde se to používá.

  5. Do složky služeb s názvem NotificationActionService přidejte další soubor nebo třídu Kotlin a pak přidejte následující kód.

    package com.<your_organization>.pushdemo.services
    
    import io.flutter.embedding.engine.FlutterEngine
    import io.flutter.plugin.common.MethodCall
    import io.flutter.plugin.common.MethodChannel
    
    class NotificationActionService {
        companion object {
            const val NOTIFICATION_ACTION_CHANNEL = "com.<your_organization>.pushdemo/notificationaction"
            const val TRIGGER_ACTION = "triggerAction"
            const val GET_LAUNCH_ACTION = "getLaunchAction"
        }
    
        private var notificationActionChannel : MethodChannel
        var launchAction : String? = null
    
        constructor(flutterEngine: FlutterEngine) {
            notificationActionChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, NotificationActionService.NOTIFICATION_ACTION_CHANNEL)
            notificationActionChannel.setMethodCallHandler { call, result -> handleNotificationActionCall(call, result) }
        }
    
        fun triggerAction(action: String) {
            notificationActionChannel.invokeMethod(NotificationActionService.TRIGGER_ACTION, action)
        }
    
        private fun handleNotificationActionCall(call: MethodCall, result: MethodChannel.Result) {
            when (call.method) {
                NotificationActionService.GET_LAUNCH_ACTION -> {
                    result.success(launchAction)
                }
                else -> {
                    result.notImplemented()
                }
            }
        }
    }
    

    Poznámka

    Tato třída implementuje pro kanál specifický pro platformu com.<your_organization>.pushdemo/notificationaction . To bylo definováno v části Flutter aplikace v notificationActionService.dart. V tomto případě je možné volat v obou směrech. Nezapomeňte your_organization> nahradit< vlastní organizací bez ohledu na to, kde se to používá.

  6. Do balíčku com.your_organization.pushdemo<> přidejte nový soubor nebo třídu Kotlin s názvem PushNotificationsFirebaseMessagingService a pak proveďte implementaci pomocí následujícího kódu.

    package com.<your_organization>.pushdemo
    
    import android.os.Handler
    import android.os.Looper
    import com.google.firebase.messaging.FirebaseMessagingService
    import com.google.firebase.messaging.RemoteMessage
    import com.<your_organization>.pushdemo.services.NotificationActionService
    import com.<your_organization>.pushdemo.services.NotificationRegistrationService
    
    class PushNotificationsFirebaseMessagingService : FirebaseMessagingService() {
    
        companion object {
            var token : String? = null
            var notificationRegistrationService : NotificationRegistrationService? = null
            var notificationActionService : NotificationActionService? = null
        }
    
        override fun onNewToken(token: String) {
            PushNotificationsFirebaseMessagingService.token = token
            notificationRegistrationService?.refreshRegistration()
        }
    
        override fun onMessageReceived(message: RemoteMessage) {
            message.data.let {
                Handler(Looper.getMainLooper()).post {
                    notificationActionService?.triggerAction(it.getOrDefault("action", null))
                }
            }
        }
    }
    

    Poznámka

    Tato třída zodpovídá za zpracování oznámení, když je aplikace spuštěná v popředí. Podmíněně zavolá triggerAction ve službě NotificationActionService , pokud je akce zahrnutá v datové části oznámení přijaté v onMessageReceived. To bude také volat refreshRegistration v NotificationRegistrationService , když se token Firebase znovu vygeneruje přepsáním funkce onNewToken .

    Znovu dbejte na to, abyste your_organization> nahradili< vlastní organizací bez ohledu na to, kde se používá.

  7. V AndroidManifest.xml (app>src>main) přidejte PushNotificationsFirebaseMessagingService do dolní části elementu aplikace s filtrem záměru com.google.firebase.MESSAGING_EVENT .

    <manifest>
        <application>
            <!-- EXISTING MANIFEST CONTENT -->
             <service
                android:name="com.<your_organization>.pushdemo.PushNotificationsFirebaseMessagingService"
                android:exported="false">
                <intent-filter>
                    <action android:name="com.google.firebase.MESSAGING_EVENT" />
                </intent-filter>
            </service>
        </application>
    </manifest>
    
  8. V části DeviceInstallationService se ujistěte, že se v horní části souboru nacházejí následující importy.

    package com.<your_organization>.pushdemo
    import com.<your_organization>.pushdemo.services.PushNotificationsFirebaseMessagingService
    

    Poznámka

    Nahraďte< your_organization> vlastní hodnotou vaší organizace.

  9. Aktualizujte zástupný text Placeholder_Get_Value_From_FirebaseMessagingService_Implementation , aby získal hodnotu tokenu z PushNotificationFirebaseMessagingService.

    fun getDeviceToken() : String {
        if(!playServicesAvailable) {
            throw Exception(getPlayServicesError())
        }
    
        // Get token from the PushNotificationsFirebaseMessagingService.token field.
        val token = PushNotificationsFirebaseMessagingService.token
    
        if (token.isNullOrBlank()) {
            throw Exception("Unable to resolve token for FCM.")
        }
    
        return token
    }
    
  10. V části MainActivity se ujistěte, že se v horní části souboru nacházejí následující importy.

    package com.<your_organization>.pushdemo
    
    import android.content.Intent
    import android.os.Bundle
    import com.google.android.gms.tasks.OnCompleteListener
    import com.google.firebase.iid.FirebaseInstanceId
    import com.<your_organization>.pushdemo.services.DeviceInstallationService
    import com.<your_organization>.pushdemo.services.NotificationActionService
    import com.<your_organization>.pushdemo.services.NotificationRegistrationService
    import io.flutter.embedding.android.FlutterActivity
    

    Poznámka

    Nahraďte< your_organization> vlastní hodnotou vaší organizace.

  11. Přidejte proměnnou pro uložení odkazu na službu DeviceInstallationService.

    private lateinit var deviceInstallationService: DeviceInstallationService
    
  12. Přidejte funkci s názvem processNotificationActions , která zkontroluje, jestli má záměr další hodnotu s názvem action. Podmíněně tuto akci aktivujte nebo ji uložte pro pozdější použití, pokud se akce zpracovává během spouštění aplikace.

     private fun processNotificationActions(intent: Intent, launchAction: Boolean = false) {
        if (intent.hasExtra("action")) {
            var action = intent.getStringExtra("action");
    
            if (action.isNotEmpty()) {
                if (launchAction) {
                    PushNotificationsFirebaseMessagingService.notificationActionService?.launchAction = action
                }
                else {
                    PushNotificationsFirebaseMessagingService.notificationActionService?.triggerAction(action)
                }
            }
        }
    }
    
  13. Přepište funkci onNewIntent tak, aby volala processNotificationActions.

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        processNotificationActions(intent)
    }
    

    Poznámka

    Vzhledem k tomu , LaunchMode pro MainActivity je nastavena na SingleTop, intent se odešle do existující instance Activity prostřednictvím funkce onNewIntent místo funkce onCreate , takže musíte zpracovat příchozí intent ve funkcích onCreate i onNewIntent .

  14. Přepište funkci onCreate a nastavte deviceInstallationService na novou instanci deviceInstallationService.

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        flutterEngine?.let {
            deviceInstallationService = DeviceInstallationService(context, it)
        }
    }
    
  15. Nastavte vlastnosti notificationActionService a notificationRegistrationService na PushNotificationFirebaseMessagingServices.

    flutterEngine?.let {
      deviceInstallationService = DeviceInstallationService(context, it)
      PushNotificationsFirebaseMessagingService.notificationActionService = NotificationActionService(it)
      PushNotificationsFirebaseMessagingService.notificationRegistrationService = NotificationRegistrationService(it)
    }
    
  16. Ve stejné funkci podmíněně volejte FirebaseInstanceId.getInstance().instanceId. Implementujte OnCompleteListener a nastavte výslednou hodnotu tokenu pro PushNotificationFirebaseMessagingService před voláním refreshRegistration.

    if(deviceInstallationService?.playServicesAvailable) {
        FirebaseInstanceId.getInstance().instanceId
            .addOnCompleteListener(OnCompleteListener { task ->
                if (!task.isSuccessful)
                    return@OnCompleteListener
    
                PushNotificationsFirebaseMessagingService.token = task.result?.token
                PushNotificationsFirebaseMessagingService.notificationRegistrationService?.refreshRegistration()
            })
    }
    
  17. Zůstaňte v onCreate a na konci funkce volejte processNotificationActions . Jako argument launchAction použijte hodnotu true, která označuje, že se tato akce zpracovává během spouštění aplikace.

    processNotificationActions(this.intent, true)
    

Poznámka

Abyste mohli dál dostávat nabízená oznámení, musíte aplikaci při každém spuštění znovu zaregistrovat a zastavit ji v ladicí relaci.

Konfigurace nativního projektu iOS pro nabízená oznámení

Konfigurace cíle runneru a souboru Info.plist

  1. V editoru Visual Studio Code se stisknutou klávesou Control + klikněte na složku ios a pak zvolte Open in Xcode (Otevřít v Xcode).

  2. V Xcode klikněte na Runner ( xcodeproj v horní části, ne na složku), vyberte cíl Runneru a pak podepisování & Schopnosti. Vyberte konfiguraci Všechna sestavení a zvolte svůj vývojářský účet pro tým. Ujistěte se, že je zaškrtnutá možnost Automaticky spravovat podepisování a že jsou automaticky vybrány podpisový certifikát a profil zřizování.

    Poznámka

    Pokud se nová hodnota zřizovacího profilu nezobrazuje, zkuste aktualizovat profily podpisové identity tak, že vybereteXcode Preferences Account (Účetpředvoleb>Xcode>) a pak výběrem tlačítka Stáhnout ruční profily stáhnete profily.

  3. Klikněte na + Schopnost a vyhledejte Nabízená oznámení. Tuto možnost přidáte poklikáním na Nabízená oznámení.

  4. Otevřete Soubor Info.plist a nastavte Minimální verze systému na 13.0.

    Poznámka

    Pro účely tohoto kurzu jsou podporována pouze zařízení se systémem iOS 13.0 a novějším , ale můžete ho rozšířit o zařízení se staršími verzemi.

  5. Otevřete Runner.entitlements a ujistěte se, že je nastavení prostředí APS nastavené na vývoj.

Zpracování nabízených oznámení pro iOS

  1. Ovládací prvek + Klikněte na složku Runner (v rámci projektu Runner) a pak jako název zvolte Nová skupina používající služby .

  2. Ovládací prvek + Klikněte na složku Služby a pak zvolte Nový soubor.... Pak zvolte Swift File (Soubor Swift) a klikněte na Next (Další). Jako název zadejte DeviceInstallationService a pak klikněte na Vytvořit.

  3. Implementujte DeviceInstallationService.swift pomocí následujícího kódu.

    import Foundation
    
    class DeviceInstallationService {
    
        enum DeviceRegistrationError: Error {
            case notificationSupport(message: String)
        }
    
        var token : Data? = nil
    
        let DEVICE_INSTALLATION_CHANNEL = "com.<your_organization>.pushdemo/deviceinstallation"
        let GET_DEVICE_ID = "getDeviceId"
        let GET_DEVICE_TOKEN = "getDeviceToken"
        let GET_DEVICE_PLATFORM = "getDevicePlatform"
    
        private let deviceInstallationChannel : FlutterMethodChannel
    
        var notificationsSupported : Bool {
            get {
                if #available(iOS 13.0, *) {
                    return true
                }
                else {
                    return false
                }
            }
        }
    
        init(withBinaryMessenger binaryMessenger : FlutterBinaryMessenger) {
            deviceInstallationChannel = FlutterMethodChannel(name: DEVICE_INSTALLATION_CHANNEL, binaryMessenger: binaryMessenger)
            deviceInstallationChannel.setMethodCallHandler(handleDeviceInstallationCall)
        }
    
        func getDeviceId() -> String {
            return UIDevice.current.identifierForVendor!.description
        }
    
        func getDeviceToken() throws -> String {
            if(!notificationsSupported) {
                let notificationSupportError = getNotificationsSupportError()
                throw DeviceRegistrationError.notificationSupport(message: notificationSupportError)
            }
    
            if (token == nil) {
                throw DeviceRegistrationError.notificationSupport(message: "Unable to resolve token for APNS.")
            }
    
            return token!.reduce("", {$0 + String(format: "%02X", $1)})
        }
    
        func getDevicePlatform() -> String {
            return "apns"
        }
    
        private func handleDeviceInstallationCall(call: FlutterMethodCall, result: @escaping FlutterResult) {
            switch call.method {
            case GET_DEVICE_ID:
                result(getDeviceId())
            case GET_DEVICE_TOKEN:
                getDeviceToken(result: result)
            case GET_DEVICE_PLATFORM:
                result(getDevicePlatform())
            default:
                result(FlutterMethodNotImplemented)
            }
        }
    
        private func getDeviceToken(result: @escaping FlutterResult) {
            do {
                let token = try getDeviceToken()
                result(token)
            }
            catch let error {
                result(FlutterError(code: "UNAVAILABLE", message: error.localizedDescription, details: nil))
            }
        }
    
        private func getNotificationsSupportError() -> String {
    
            if (!notificationsSupported) {
                return "This app only supports notifications on iOS 13.0 and above. You are running \(UIDevice.current.systemVersion)"
            }
    
            return "An error occurred preventing the use of push notifications."
        }
    }
    

    Poznámka

    Tato třída implementuje pro kanál specifický pro platformu com.<your_organization>.pushdemo/deviceinstallation . To bylo definováno v části Flutter aplikace v deviceInstallationService.dart. V tomto případě se volání provádí ze společného kódu na nativního hostitele. Nezapomeňte your_organization> nahradit< vlastní organizací bez ohledu na to, kde se to používá.

    Tato třída poskytuje jedinečné ID (pomocí hodnoty UIDevice.identifierForVendor ) jako součást datové části registrace centra oznámení.

  4. Do složky Services přidejte další soubor Swift s názvem NotificationRegistrationService a pak přidejte následující kód.

    import Foundation
    
    class NotificationRegistrationService {
    
        let NOTIFICATION_REGISTRATION_CHANNEL = "com.<your_organization>.pushdemo/notificationregistration"
        let REFRESH_REGISTRATION = "refreshRegistration"
    
        private let notificationRegistrationChannel : FlutterMethodChannel
    
        init(withBinaryMessenger binaryMessenger : FlutterBinaryMessenger) {
           notificationRegistrationChannel = FlutterMethodChannel(name: NOTIFICATION_REGISTRATION_CHANNEL, binaryMessenger: binaryMessenger)
        }
    
        func refreshRegistration() {
            notificationRegistrationChannel.invokeMethod(REFRESH_REGISTRATION, arguments: nil)
        }
    }
    

    Poznámka

    Tato třída implementuje pro kanál specifický pro platformu com.<your_organization>.pushdemo/notificationregistration . To bylo definováno v části Flutter aplikace v části NotificationRegistrationService.dart. V tomto případě se volání provádí z nativního hostitele do společného kódu. Znovu dbejte na to, abyste your_organization> nahradili< vlastní organizací bez ohledu na to, kde se to používá.

  5. Do složky Services přidejte další soubor Swift s názvem NotificationActionService a pak přidejte následující kód.

    import Foundation
    
    class NotificationActionService {
    
        let NOTIFICATION_ACTION_CHANNEL = "com.<your_organization>.pushdemo/notificationaction"
        let TRIGGER_ACTION = "triggerAction"
        let GET_LAUNCH_ACTION = "getLaunchAction"
    
        private let notificationActionChannel: FlutterMethodChannel
    
        var launchAction: String? = nil
    
        init(withBinaryMessenger binaryMessenger: FlutterBinaryMessenger) {
            notificationActionChannel = FlutterMethodChannel(name: NOTIFICATION_ACTION_CHANNEL, binaryMessenger: binaryMessenger)
            notificationActionChannel.setMethodCallHandler(handleNotificationActionCall)
        }
    
        func triggerAction(action: String) {
           notificationActionChannel.invokeMethod(TRIGGER_ACTION, arguments: action)
        }
    
        private func handleNotificationActionCall(call: FlutterMethodCall, result: @escaping FlutterResult) {
            switch call.method {
            case GET_LAUNCH_ACTION:
                result(launchAction)
            default:
                result(FlutterMethodNotImplemented)
            }
        }
    }
    

    Poznámka

    Tato třída implementuje pro kanál specifický pro platformu com.<your_organization>.pushdemo/notificationaction . To bylo definováno v části Flutter aplikace v notificationActionService.dart. V tomto případě je možné volat v obou směrech. Nezapomeňte your_organization> nahradit< vlastní organizací bez ohledu na to, kde se to používá.

  6. V souboru AppDelegate.swift přidejte proměnné pro uložení odkazu na služby, které jste vytvořili dříve.

    var deviceInstallationService : DeviceInstallationService?
    var notificationRegistrationService : NotificationRegistrationService?
    var notificationActionService : NotificationActionService?
    
  7. Přidejte funkci s názvem processNotificationActions pro zpracování dat oznámení. Podmíněně tuto akci aktivujte nebo ji uložte pro pozdější použití, pokud se akce zpracovává během spouštění aplikace.

    func processNotificationActions(userInfo: [AnyHashable : Any], launchAction: Bool = false) {
        if let action = userInfo["action"] as? String {
            if (launchAction) {
                notificationActionService?.launchAction = action
            }
            else {
                notificationActionService?.triggerAction(action: action)
            }
        }
    }
    
  8. Přepište funkci didRegisterForRemoteNotificationsWithDeviceToken , která nastavuje hodnotu tokenu pro DeviceInstallationService. Pak zavolejte refreshRegistration pro NotificationRegistrationService.

    override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
      deviceInstallationService?.token = deviceToken
      notificationRegistrationService?.refreshRegistration()
    }
    
  9. Přepište funkci didReceiveRemoteNotification , která předává argument userInfo funkci processNotificationActions .

    override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
        processNotificationActions(userInfo: userInfo)
    }
    
  10. Přepište funkci didFailToRegisterForRemoteNotificationsWithError a zaprotokolujte chybu.

    override func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print(error);
    }
    

    Poznámka

    To je velmi zástupný symbol. V produkčních scénářích budete chtít implementovat správné protokolování a zpracování chyb.

  11. V souboru didFinishLaunchingWithOptions vytvořte instanci proměnnýchdeviceInstallationService, notificationRegistrationService a notificationActionService .

    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    
    deviceInstallationService = DeviceInstallationService(withBinaryMessenger: controller.binaryMessenger)
    notificationRegistrationService = NotificationRegistrationService(withBinaryMessenger: controller.binaryMessenger)
    notificationActionService = NotificationActionService(withBinaryMessenger: controller.binaryMessenger)
    
  12. Ve stejné funkci podmíněně požádáte o autorizaci a zaregistrujete vzdálená oznámení.

    if #available(iOS 13.0, *) {
      UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) {
          (granted, error) in
    
          if (granted)
          {
              DispatchQueue.main.async {
                  let pushSettings = UIUserNotificationSettings(types: [.alert, .sound, .badge], categories: nil)
                  application.registerUserNotificationSettings(pushSettings)
                  application.registerForRemoteNotifications()
              }
          }
      }
    }
    
  13. Pokud launchOptions obsahuje klíč remoteNotification , zavolejte processNotificationActions na konci funkce didFinishLaunchingWithOptions . Předejte výsledný objekt userInfo a jako argument launchAction použijte true. Hodnota true označuje, že se akce zpracovává během spouštění aplikace.

    if let userInfo = launchOptions?[.remoteNotification] as? [AnyHashable : Any] {
        processNotificationActions(userInfo: userInfo, launchAction: true)
    }
    

Testování řešení

Teď můžete otestovat odesílání oznámení prostřednictvím back-endové služby.

Odeslání testovacího oznámení

  1. Otevřete novou kartu v nástroji Postman.

  2. Nastavte požadavek na POST a zadejte následující adresu:

    https://<app_name>.azurewebsites.net/api/notifications/requests
    
  3. Pokud jste se rozhodli dokončit část Ověřování klientů pomocí klíče rozhraní API , nezapomeňte nakonfigurovat hlavičky požadavku tak, aby obsahovaly hodnotu klíče rozhraní API .

    Klíč Hodnotu
    klíč rozhraní API <your_api_key>
  4. Zvolte nezpracovanou možnost pro text, pak v seznamu možností formátování zvolte JSON a pak přidejte nějaký zástupný obsah JSON :

    {
        "text": "Message from Postman!",
        "action": "action_a"
    }
    
  5. Vyberte tlačítko Kód , které je pod tlačítkem Uložit v pravém horním rohu okna. Požadavek by měl při zobrazení html vypadat podobně jako v následujícím příkladu (v závislosti na tom, jestli jste zahrnuli hlavičku apikey ):

    POST /api/notifications/requests HTTP/1.1
    Host: https://<app_name>.azurewebsites.net
    apikey: <your_api_key>
    Content-Type: application/json
    
    {
        "text": "Message from backend service",
        "action": "action_a"
    }
    
  6. Spusťte aplikaci PushDemo na jedné nebo obou cílových platformách (Android a iOS).

    Poznámka

    Pokud testujete na Androidu, ujistěte se, že neběžíte v ladění, nebo pokud byla aplikace nasazená spuštěním aplikace, vynuťte ukončení aplikace a spusťte ji znovu ze spouštěče.

  7. V aplikaci PushDemo klepněte na tlačítko Zaregistrovat .

  8. Zpět v Nástroji Postmanzavřete okno Generovat fragmenty kódu (pokud jste to ještě neudělali) a klikněte na tlačítko Odeslat .

  9. Ověřte, že se v nástroji Postman zobrazí odpověď 200 OK a že se v aplikaci zobrazí upozornění s přijatou akcí ActionA.

  10. Zavřete aplikaci PushDemo a potom v nástroji Postman znovu klikněte na tlačítko Odeslat.

  11. Ověřte, že se v Nástroji Postman znovu zobrazí odpověď 200 OK. Ověřte, že se v oznamovací oblasti aplikace PushDemo zobrazí oznámení se správnou zprávou.

  12. Klepnutím na oznámení potvrďte, že se otevře aplikace a zobrazí se upozornění akcePři přijetí akce .

  13. Zpátky v Nástroji Postman upravte text předchozí žádosti tak, aby se odeslalo tiché oznámení, které místo action_a pro hodnotu akce zadá action_b.

    {
        "action": "action_b",
        "silent": true
    }
    
  14. Když je aplikace stále otevřená, klikněte na tlačítko Odeslat v nástroji Postman.

  15. Ověřte, že v nástroji Postman dostanete odpověď 200 OK a že se upozornění zobrazí v aplikaci s přijatou akcí ActionB místo akce ActionA.

  16. Zavřete aplikaci PushDemo a potom v nástroji Postman znovu klikněte na tlačítko Odeslat.

  17. Ověřte, že v nástroji Postman obdržíte odpověď 200 OK a že se v oznamovací oblasti nezobrazuje tiché oznámení.

Řešení potíží

Žádná odpověď z back-endové služby

Při místním testování se ujistěte, že je back-endová služba spuštěná a používá správný port.

Pokud testujete aplikaci Azure API, zkontrolujte, jestli je služba spuštěná, nasazená a spuštěná bez chyby.

Při testování prostřednictvím klienta nezapomeňte zkontrolovat, že jste v nástroji Postman nebo v konfiguraci mobilní aplikace zadali základní adresu správně. Základní adresa by při místním testování měla být https://<api_name>.azurewebsites.net/ nebo https://localhost:5001/ .

Nepřijímají se oznámení v Androidu po spuštění nebo zastavení ladicí relace

Po spuštění nebo zastavení ladicí relace se znovu zaregistrujte. Ladicí program způsobí vygenerování nového tokenu Firebase . Musí se také aktualizovat instalace centra oznámení.

Příjem stavového kódu 401 z back-endové služby

Ověřte, že nastavujete hlavičku požadavku apikey a že tato hodnota odpovídá té, kterou jste nakonfigurovali pro back-endovou službu.

Pokud se při místním testování zobrazí tato chyba, ujistěte se, že hodnota klíče, kterou jste definovali v konfiguraci klienta, odpovídá hodnotě nastavení uživatele Authentication:ApiKey používané rozhraním API.

Pokud testujete pomocí aplikace API, ujistěte se, že hodnota klíče v konfiguračním souboru klienta odpovídá nastavení aplikace Authentication:ApiKey , které používáte v aplikaci API.

Poznámka

Pokud jste toto nastavení vytvořili nebo změnili po nasazení back-endové služby, musíte službu restartovat, aby se projevilo.

Pokud jste se rozhodli nedokončíte část Ověřování klientů pomocí klíče rozhraní API , ujistěte se, že jste nepoužádali atribut Authorize na třídu NotificationsController .

Příjem stavového kódu 404 z back-endové služby

Ověřte správnost koncového bodu a metody požadavku HTTP. Koncové body by například měly být:

  • [PUT]https://<api_name>.azurewebsites.net/api/notifications/installations
  • [ODSTRANIT]https://<api_name>.azurewebsites.net/api/notifications/installations/<installation_id>
  • [POST]https://<api_name>.azurewebsites.net/api/notifications/requests

Nebo při místním testování:

  • [PUT]https://localhost:5001/api/notifications/installations
  • [ODSTRANIT]https://localhost:5001/api/notifications/installations/<installation_id>
  • [POST]https://localhost:5001/api/notifications/requests

Při zadávání základní adresy v klientské aplikaci se ujistěte, že končí na /. Základní adresa by při místním testování měla být https://<api_name>.azurewebsites.net/ nebo https://localhost:5001/ .

Nepovedlo se zaregistrovat a zobrazila se chybová zpráva centra oznámení

Ověřte, že je testovací zařízení připojeno k síti. Pak určete stavový kód odpovědi HTTP nastavením zarážky pro kontrolu hodnoty vlastnosti StatusCode v HttpResponse.

Pokud je to možné, projděte si předchozí návrhy řešení potíží na základě stavového kódu.

Nastavte zarážku na řádky, které vracejí tyto konkrétní stavové kódy pro příslušné rozhraní API. Pak zkuste volat back-endovou službu při místním ladění.

Pomocí příslušné datové části ověřte, že back-endová služba funguje podle očekávání prostřednictvím nástroje Postman . Použijte skutečnou datovou část vytvořenou kódem klienta pro danou platformu.

Projděte si části konfigurace specifické pro platformu a ujistěte se, že nedošlo k vynechání žádných kroků. Zkontrolujte, jestli se pro příslušnou platformu překládají vhodné hodnoty proměnných installation id a token .

Nepodařilo se přeložit ID zařízení, zobrazuje se chybová zpráva

Projděte si části konfigurace specifické pro platformu a ujistěte se, že nedošlo k vynechání žádných kroků.

Další kroky

Teď byste měli mít základní aplikaci Flutter připojenou k centru oznámení prostřednictvím back-endové služby a mohli odesílat a přijímat oznámení.

Pravděpodobně budete muset přizpůsobit příklad použitý v tomto kurzu tak, aby odpovídal vašemu vlastnímu scénáři. Doporučuje se také implementace robustnějšího zpracování chyb, logiky opakování a protokolování.

Visual Studio App Center je možné rychle začlenit do mobilních aplikací, které poskytují analýzy a diagnostiku , které vám pomůžou při řešení potíží.