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 Stáhnout ukázkovou

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

Back-end základního webového rozhraní API ASP.NET se používá ke zpracování registrace zařízení pro klienta s využitím nejnovějšího a nejlepšího přístupu instalace. Služba bude také posí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 Registrace z back-endu vaší aplikace.

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

Požadavky

Pokud chcete postup sledovat, budete potřebovat:

  • Předplatné Azure, kde můžete vytvářet a spravovat prostředky.
  • Sada nástrojů Flutter (spolu s požadavky).
  • editoru Visual Studio Code s nainstalovanými modul y plug-in Flutter a Dart.
  • CocoaPods nainstalovaná pro správu závislostí knihovny.
  • Možnost spustit aplikaci na android (fyzická nebo emulátorová zařízení) nebo iOS (jenom fyzická zařízení).

Pro Android musíte mít:

  • Vývojář odemčený fyzický zařízení nebo emulátor (se spuštěným rozhraním API 26 a novějším s nainstalovanými službami Google Play).

Pro iOS musíte mít:

Poznámka

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

Můžete postupovat podle kroků v tomto prvním příkladu zásad bez předchozího prostředí. Můžete se ale seznámit s následujícími aspekty.

Uvedené kroky jsou specifické pro macOS . Na Windows můžete sledovat přeskočením aspektů iOS.

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

V této části jste nastavili Firebase Cloud Messaging (FCM) a 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, který zadá PushDemo jako název projektu .

    Poznámka

    Pro vás se vygeneruje jedinečný název. Ve výchozím nastavení se skládá z malé varianty názvu, který jste zadali, plus vygenerované číslo oddělené pomlčkou. Tuto možnost můžete změnit, pokud chcete, aby byla 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 na aplikaci pro Android proveďte následující kroky.

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

      Zadejte název balíčku

    2. Vyberte Zaregistrovataplikace .

    3. Vyberte Stáhnout google-services.json. Potom 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 v konzole

      Poznámka

      Pokud tlačítko Pokračovat v konzole není povolené, protože ověřit instalaci, zvolte Přeskočit tento krok.

  4. V konzole Firebase vyberte ozubené kolo projektu. Pak vybertenastavení projektu .

    Vyberte nastavení projektu

    Poznámka

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

  5. Přepněte na kartu Cloud Messaging nahoře. 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 v Apple a zaregistrujte si také nabízená oznámení.

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

    id aplikací portálu pro zřizování pro iOS

  2. Na obrazovce Zaregistrovat nový identifikátor vyberte přepínač ID aplikací. Pak vyberte Pokračovat.

    portálu pro zřizování pro iOS zaregistrujte novou stránku ID

  3. Aktualizujte následující tři hodnoty nové aplikace a pak vyberte Pokračovat:

    • Popis: Zadejte popisný název aplikace.

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

      stránka ID aplikace portálu pro zřizování pro iOS

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

      Formulář pro registraci nového ID aplikace

      Tato akce vygeneruje ID aplikace a požadavky, které potvrdíte. Vyberte Pokračovata pak výběrem Zaregistrovat potvrďte nové ID aplikace.

      Potvrzení nového ID aplikace

      Jakmile vyberete Zaregistrovat, zobrazí se nové ID aplikace jako řádková položka na stránce Certifikáty, identifikátory & profily.

  4. Na stránce Certifikáty & profily v části Identifikátory vyhledejte položku řádku ID aplikace, kterou jste vytvořili. Potom výběrem jeho řádku zobrazte obrazovku Upravit konfiguraci ID aplikace.

Vytvoření certifikátu pro Notification Hubs

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

  1. Vytvoření certifikátu p12 push, který lze nahrát přímo do centra oznámení (původní přístup)

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

Novější přístup má řadu výhod, jak je uvedeno v ověřování založeném na tokenech http/2 () pro službu APNS. Vyžaduje se méně kroků, ale je také vyžadováno pro konkrétní scénáře. Pro oba přístupy jsou však k dispozici kroky, protože oba budou fungovat pro účely tohoto kurzu.

MOŽNOST 1: Vytvoření certifikátu push p12, který lze nahrát přímo do centra oznámení
  1. Na macu spusťte nástroj Keychain Access. Dá se otevřít ze složky Nástrojů nebo ze složky Jiné na Launchpadu.

  2. Vyberte Přístup ke klíčence, rozbaltePomocníka 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í access řetězce klíčů vybere první položku v seznamu. Může to být problém, pokud jste v kategorii Certifikáty a certifikační autorita Apple Worldwide Developer Relations není první položkou v seznamu. Před vygenerováním žádosti o podepsání certifikátu se ujistěte, že máte neklíčovou položku nebo je vybraná certifikační autorita apple Worldwide Developer Relations klíč.

  3. Vybertee-mailovou adresu uživatele , zadejte hodnotu běžný název, ujistěte se, že jste zadali Uloženo na diska pak vyberte Pokračovat. E-mailová adresa certifikační autority prázdná, protože není nutná.

    očekávané informace o certifikátu

  4. Do Uložit jakozadejte název souboru Žádosti o podepsání certifikátu (CSR) , vyberte umístění v Kdea pak vyberte Uložit.

    Zvolit název souboru pro certifikátu

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

  5. Zpět na stránce Certifikáty, identifikátory & profily na portálu pro zřizování iOS, posuňte se dolů na zaškrtnutou možnost nabízená oznámení a pak vyberte Konfigurovat vytvořit certifikát.

    upravit stránku ID aplikace

  6. Zobrazí se okno službě Apple Push Notification TLS/SSL Certificates. V části Vývoj certifikátů 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á vývojový certifikát. Stejný proces se používá při registraci produkčního certifikátu. Při odesílání oznámení se ujistěte, že používáte stejný typ certifikátu.

  7. Vyberte Zvolte soubor, přejděte do umístění, kam jste uložili soubor CSRa 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 se uloží.

    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.

    Vyhledání souboru certifikátu ve složce Stažené soubory

    Poznámka

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

  9. Poklikejte na stažený certifikát push 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ů klíčenky 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 mít přidružený odpovídající identifikátor sady.

  10. V okně Přístup ke klíčence řízení + Klikněte na nového certifikátu 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é. Chcete-li 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í APN.

    Poznámka

    Název a umístění 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ý lze použít pro ověřování na základě tokenu
  1. Poznamenejte si následující podrobnosti:

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

    Poznámka

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

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

  4. Zadejte vhodnou hodnotu Název klíče a potom zaškrtněte možnost služby Apple Push Notifications Service (APNS) a potom klikněte na Pokračovata potom na další obrazovce Zaregistrovat.

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

    Poznámka

    Nezapomeňte soubor p8 uchovávat na bezpečném místě (a uložit zálohu). Po stažení klíče se nedá znovu stáhnout, protože se odebere kopie serveru.

  6. V Klíčeklikněte na klíč, který jste vytvořili (nebo existující klíč, pokud jste se rozhodli tuto možnost použít).

  7. Poznamenejte si hodnotu ID klíče .

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

    privátní klíč -----BEGIN-----
    <key_value>
    privátní klíč -----END-----

    Poznámka

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

Na konci těchto kroků byste měli mít následující informace pro pozdější použití v Konfigurace centra oznámení s informacemi 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 vyberte + a vytvořte nový profil. Zobrazí se obrazovka Registrace nového zřizovacího profilu.

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

    seznam zřizovacích profilů

  3. Dále vyberte ID aplikace, které jste vytvořili, z rozevíracího seznamu ID aplikace a vyberte Pokračovat.

    Vyberte ID aplikace

  4. V okně Vyberte certifikáty vyberte vývojový certifikát, který používáte pro 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áš vývojový certifikát. Pokud neexistuje, musíte ho vytvořit, protože se jedná o předpoklad pro účely tohoto kurzu. Certifikáty pro vývojáře je možné vytvářet naportálu pro vývojáře Apple prostřednictvím Xcode nebo v Visual Studio.

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

  6. V okně Vyberte certifikáty vyberte vytvořený vývojový certifikát. 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 Název zřizovacího profilua vyberte Vygenerovat.

    zvolte název 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 na něj 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řitprostředku, vyhledejte a zvoltecentra oznámení a potom klikněte na Vytvořit.

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

    ZÁKLADNÍ PODROBNOSTI

    Předplatné: v rozevíracím seznamu Zvolte cílovou předplatného .
    skupina prostředků: Vytvořit novou skupinu prostředků (nebo vybrat existující)

    PODROBNOSTI o oboru názvů

    Namespace centra oznámení : Zadejte globálně jedinečný název centra oznámení

    Poznámka

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

    podrobnosti centra oznámení

    Notification Hub: Zadejte název centra oznámení
    umístění : Zvolte vhodné umístění z rozevíracího seznamu
    cenová úroveň : ponechat 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 na tento prostředek.

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

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

  7. Poznamenejte si hodnoty názvu zásady společně s odpovídajícími hodnotami připojovacího řetězce.

Konfigurace centra oznámení s informacemi o službě APNS

V části Notification Servicesvyberte Apple postupujte podle příslušných kroků na základě přístupu, který jste zvolili dříve v části Vytvoření certifikátu pro službu Notification Hubs.

Poznámka

Production použijte pro režim aplikace jenom v případě, že chcete odesílat nabízená oznámení uživatelům, kteří si aplikaci koupili ve Storu.

MOŽNOST 1: Použití certifikátu push .p12

  1. Vybertecertifikátu .

  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í založeného na tokenech

  1. Vyberte token.

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

    • id klíče
    • ID sady
    • id týmu
    • tokenu
  3. Zvoltesandboxu .

  4. Vyberte Uložit.

Konfigurace centra oznámení s informacemi o FCM

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

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

V této části vytvoříte back-end ASP.NET Core Web API pro zpracování registrace zařízení a odesílání oznámení do mobilní aplikace Flutter.

Vytvoření webového projektu

  1. V sady Visual Studio vyberte Soubor>Novýřešení .

  2. Vyberte rozhraní .NET Core>App>ASP.NET Core>API>Next.

  3. V dialogovém okně Konfigurace nového webového rozhraní API ASP.NET Core vyberte Target Framework.NET Core 3.1.

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

  5. Spusťte ladění (Command + Enter) a otestujte aplikaci šablony.

    Poznámka

    Aplikace šablony je nakonfigurována tak, aby jako launchUrl WeatherForecastController . Toto nastavení je nastaveno v Vlastnosti>launchSettings.json.

    Pokud se zobrazí výzva s nalezen neplatný vývojový certifikát, zpráva:

    1. Kliknutím na Ano souhlasíte se spuštěním nástroje dotnet dev-certs https. Nástroj dotnet dev-certs https pak vyzve k zadání hesla pro certifikát a heslo klíčenky.

    2. Po zobrazení výzvy k Nainstalovat a důvěřovat novémucertifikátu klikněte na Ano a zadejte heslo klíčenky.

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

  7. Odstranit WeatherForecast.cs.

  8. Nastavte místní hodnoty konfigurace pomocí nástroje Secret Manager. Oddělení tajných kódů od řešení zajišťuje, že se nedokončí ve správě zdrojového kódu. Otevřete Terminal 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ího řetězce. Poznamenali jste si je v vytvoření centra oznámení oddílu. V opačném případě je můžete vyhledat v Azure.

    NotificationHub:Name:
    V souhrnu Essentials v horní částipřehledu se podívejte na název .

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

    Poznámka

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

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

Klíče rozhraní API nejsou tak bezpečné jako tokeny, ale pro účely tohoto kurzu budou stačit. Klíč rozhraní API lze snadno nakonfigurovat prostřednictvímmiddlewaru ASP.NET .

  1. Přidejte klíč rozhraní API do místních hodnot konfigurace.

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

    Poznámka

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

  2. ŘízeníV projektu PushDemoApi klikněte na Nová složka , v nabídce Přidat klikněte na Přidat pomocí Ověřovací jakonázev složky .

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

  4. Vyberte ObecnéPrázdnýtřídy , zadejte ApiKeyAuthOptions.cs pronázev a potom klikněte na Nový přidat 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. Do ApiKeyAuthHandler.cssložky Authentication přidejte další prázdnou třídu a 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 s názvem ApiKeyAuthenticationBuilderExtensions.cspřidejte další prázdnou třídu 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 metoda rozšíření zjednodušuje kód konfigurace middlewaru v Startup.cs aby byl čitelnější a obecně srozumitelnější.

  7. V Startup.csaktualizujte metodu ConfigureServices tak, aby se ověřování pomocí klíče rozhraní API konfiguruje pod voláním služeb . AddControllers metoda.

    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 useAuthentication a UseAuthorization rozšiřující metody v IApplicationBuilder aplikace. Ujistěte se, že se tyto metody volají po UseRouting a před aplikací. UseEndpoints.

    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í UseAuthentication zaregistruje middleware, který používá dříve registrovaná schémata ověřování (ConfigureServices). Musí se volat před jakýmkoli middlewarem, který závisí na ověřování uživatelů.

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

ASP.NET Core podporuje vzor návrhu softwaru 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í prvekKlikněte na ve složce závislostí a pak zvolte Spravovat balíčky NuGet....

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

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

  4. Ovládací prvekv projektu PushDemoApi klikněte na Nová složka, v nabídce Přidat klikněte na Přidat pomocí modely jakonázev složky .

  5. OvládacíKlikněte na ve složce Modely a pak v nabídce Přidat zvolte Nový soubor....

  6. Vyberte ObecnéPrázdná třída, zadejte PushTemplates.cs pronázev a potom klepněte na tlačítko Nová přidání následující implementace.

    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 jsou definovány mimo Instalace, 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 mimo rozsah tohoto kurzu. V produkčním prostředí zvažte vlastní šablony.

  7. Do složky Models s názvem DeviceInstallation.cspřidejte další prázdnou třídu a 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. Přidejte další Prázdnou třídu do složky Models s názvem NotificationRequest.csa 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. Přidejte další Prázdnou třídu do složky Models s názvem NotificationHubOptions.csa 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. Přidejte novou složku do projektu PushDemoApi s názvem Services.

  11. Přidejte Prázdné rozhraní do složky Services s názvem INotificationService.csa 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. Do složky služby Services s názvem NotificationHubsService.cspřidejte prázdnou třídu a pak přidejte následující kód pro implementaci INotificationService rozhraní:

    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ý pro SendTemplateNotificationAsync je omezený na 20 značek. U většiny operátorů je omezena na 6, ale výraz v tomto případě obsahuje pouze ORS (||). Pokud požadavek obsahuje více než 20 značek, musí být rozděleny do více požadavků. Další podrobnosti najdete v dokumentaci směrování a výrazů značek.

  13. V Startup.csaktualizujte metodu ConfigureServices tak, aby se NotificationHubsService NotificationHubsService přidala jako jednoúčelová implementace 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í prvekKlikněte na ve složce kontrolery a pak v nabídce Přidat zvolte Nový soubor....

  2. Vyberte ASP.NET Core>třídy kontroleru webového rozhraní API, zadejte NotificationsController název názeva potom klikněte na Nový.

    Poznámka

    Pokud sledujete sady Visual Studio 2019, zvolte kontroleru rozhraní API s akcemi čtení a zápisu šablony.

  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 šablony tak, aby byl odvozen od ControllerBase a je zdoben atributem ApiController.

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

    Poznámka

    Základní třída Controller poskytuje podporu pro zobrazení, ale v tomto případě to není potřeba, takže ControllerBase lze použít. Pokud sledujete sady Visual Studio 2019, můžete tento krok přeskočit.

  5. Pokud jste se rozhodli dokončit Ověřování klientů pomocí oddílu klíč rozhraní API, měli byste ozdobit NotificationsController také atributem Authorize.

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

    readonly INotificationService _notificationService;
    
    public NotificationsController(INotificationService notificationService)
    {
        _notificationService = notificationService;
    }
    
  7. V launchSettings.json (ve složce Vlastnosti) 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) a ověřte, že aplikace pracuje s novým NotificationsController a vrátí 401 Neautorizováno stavu.

    Poznámka

    Visual Studio nemusí automaticky spustit aplikaci v prohlížeči. K otestování rozhraní API od tohoto okamžiku použijete Postman.

  9. Na nové kartě Postman nastavte požadavek na GET. Zadejte níže uvedenou adresu a nahraďte zástupný applicationUrl https applicationUrl nalezeným vlaunchSettings.jsonvlastností .

    <applicationUrl>/api/notifications
    

    Poznámka

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

  10. Pokud jste se rozhodli dokončit Ověření klientů pomocí oddílu klíč rozhraní API, nezapomeňte nakonfigurovat hlavičky požadavku tak, aby zahrnovaly klíč rozhraní APIkey hodnotu.

    Klíč Hodnota
    apikey <your_api_key>
  11. Klikněte na tlačítko Odeslat.

    Poznámka

    Měli byste obdržet stav 200 OK s určitým obsahem JSON .

    Pokud se zobrazí upozornění ověření certifikátu SSL, můžete v nastavenínastavení přepnout ověření certifikátu SSL Post man.

  12. Nahraďte šablonované metody třídy v NotificationsController.cs 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ď vytvoříte aplikace API v azure App Service pro hostování back-endové služby.

  1. Přihlaste se k webu azure Portal.

  2. Klikněte na Vytvořitprostředku, vyhledejte a zvolteaplikace API a potom klikněte na Vytvořit.

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

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

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

    skupina prostředků :
    Zvolte stejnou skupinu prostředků jste vytvořili centrum oznámení.

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

    Poznámka

    Změňte výchozí možnost 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 zablokování požadavků http.

    Application Insights:
    Ponechte navrženou možnost (pomocí názvu se vytvoří nový prostředek) nebo vyberte existující prostředek.

  4. Po zřízení aplikace API přejděte na tento prostředek.

  5. Poznamenejte si vlastnost adresy URL v souhrnu Essentials v horní částipřehledu . Tato adresa URL je váš back-endový koncový bod, který se použije později v tomto kurzu.

    Poznámka

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

  6. V seznamu vyberte konfigurace (v částinastavení ).

  7. Pro každé z níže uvedených nastavení klepněte na tlačítko Nové nastavení aplikace zadejte Název a Hodnotaa potom klepněte na tlačítko OK.

    Jméno Hodnota
    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 se vyžaduje jenom v případě, že jste se rozhodli dokončit ověřování klientů pomocí oddílu klíč rozhraní API. V produkčních scénářích se můžete podívat na možnosti, jako je azure KeyVault. Ty byly přidány jako nastavení aplikace pro zjednodušení v tomto případě.

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

Publikování back-endové služby

Dále nasadíte aplikaci 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 sledujete visual studio 2019 ve Windows, tok publikování se bude lišit. Viz Publikování do služby Azure App Service ve Windows.

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

  2. ovládací prvekKlikněte projektu PushDemoApi PushDemoApi a pak v nabídce Publikovat zvolte Publikovat do Azure....

  3. Pokud k tomu budete vyzváni, postupujte podle toku ověřování. Použijte účet, který jste použili v předchozím vytvoření oddílu aplikace API.

  4. Vyberte aplikaci API služby Azure App Service, kterou jste vytvořili dříve ze seznamu jako cíl publikování, a potom klikněte na Publikovat.

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

Ověřování publikovaného rozhraní API

  1. V Nástroj Postman otevřít novou kartu, nastavte požadavek na PUT a zadejte adresu níže. Zástupný symbol nahraďte základní adresou, kterou jste si poznamenali v předchozím publikujte back-endovou službu oddílu.

    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 Ověření klientů pomocí oddílu klíč rozhraní API, nezapomeňte nakonfigurovat hlavičky požadavku tak, aby zahrnovaly klíč rozhraní APIkey hodnotu.

    Klíč Hodnota
    apikey <your_api_key>
  3. Zvolte možnost nezpracované protextu a pak v seznamu možností formátu vyberte JSON a pak do pole se seznamem možností formátu zadejte zástupný symbol JSON:

    {}
    
  4. Klikněte na Odeslat.

    Poznámka

    Měli byste obdržet stav 422 UnprocessableEntity ze služby.

  5. Opakujte kroky 1 až 4, ale tentokrát zadáním koncového bodu požadavků ověřte, ž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 Flutter mobilní aplikaci, která implementuje nabízená oznámení multiplatformně.

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

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

Poznámka

Obvykle byste během příslušného bodu životního cyklu aplikace (nebo v rámci prvního spuštění) prováděli akce registrace (a zrušení registrace) bez explicitních vstupů registrace nebo registrace uživatele. Tento příklad však bude vyžadovat explicitní vstup uživatele, aby bylo možné tuto funkci prozkoumat a snadněji testovat.

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 Flutter: New Project command then press Enter.

  4. Zadejte push_demo pro název projektu a vyberte umístění projektu.

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

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

    Poznámka

    Při použití šablony Visual Studio Code tyto složky standardně com, příklad, <project_name>. Za předpokladu, že se mobcat používá proorganizace , měla by se struktura složek zobrazovat jako:

    • kotlin
      • modelu com
        • mobcat
          • pushdemo
  7. Zpátky v Visual Studio Codeaktualizujte hodnotu applicationId v aplikaci android>>build.gradle 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, protože organizace bude mít za následek název balíčku hodnotu com.mobcat.pushdemo.

  8. Aktualizujte atribut balíčku v souborech AndroidManifest.xml v části ladění, srchlavnía profilusrc. Ujistěte se, že hodnoty odpovídají applicationId, které 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. Aktualizujte atribut android:label v souboru AndroidManifest.xml v části src>hlavní na PushDemo. Potom přidejte atribut android:allowBackup přímo pod 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 (android>app>build.gradle), aktualizujte compileSdkVersion (v části android) tak, aby používal rozhraní API 29. Potom aktualizujte hodnoty minSdkVersion a targetSdkVersion (z oddílu defaultConfig) na 26 a 29.

    Poznámka

    Pro účely tohoto kurzu jsou podporována pouze zařízení, na kterých běží rozhraní API úrovně 26 a vyšší, ale můžete je rozšířit tak, aby podporovala zařízení se staršími verzemi.

  11. Ovládací prvekKlikněte na ve složce ios a pak zvolte Otevřít v Xcode.

  12. V Xcode klikněte na Runner (xcodeproj nahoře, ne na složku). Pak vyberte cíl spouštěče a vyberte kartu Obecné. Pokud je vybraná konfigurace sestavení Všechna, aktualizujte identifikátor sady 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, protože organizace bude mít za následek identifikátor sady hodnotu com.mobcat.PushDemo.

  13. Klikněte na Info.plist potom aktualizujte hodnotu název sady PushDemo

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

  15. Zpátky v Visual Studio Codeotevřete pubspec.yaml, přidejte balíčky http a flutter_secure_storageDart 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 Terminalzměňte adresář na složku ios (pro váš projekt Flutter). Potom spuštěním příkazu pod install nainstalujte nové pody (vyžadované balíčkem flutter_secure_storage).

  17. Ovládací prvek + Klikněte na ve složce lib a potom v nabídce zvolte Nový soubor pomocí main_page.dart jako název souboru. 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 main.dartnahraďte kód v šabloně 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álsestavte a spusťte aplikaci na každé cílové platformě, abyste mohli otestovat, že aplikace šablony běží na vašich zařízeních. Ujistěte se, že jsou podporovaná zařízení připojená.

    flutter run
    

Implementace komponent pro různé platformy

  1. OvládacíKlikněte na ve složce lib a pak v nabídce zvolte Nová složka pomocí modelů jako název složkynázev složky .

  2. Ovládací + Klikněte na ve složce modely a pak v nabídce zvolte Nový soubor pomocí device_installation.dart jako název souboru. 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 modelů přidejte nový soubor s názvem push_demo_action.dart definování výčtu podporovaných akcí v tomto příkladu.

    enum PushDemoAction {
      actionA,
      actionB,
    }
    
  4. Přidejte do projektu novou složku s názvem services 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, protože organizace bude mít za následek MethodChannel název com.mobcat.pushdemo/deviceinstallation.

    Tato třída zapouzdřuje práci s základní nativní platformou za účelem získání požadovaných podrobností o instalaci zařízení. MethodChannel usnadňuje obousměrnou asynchronní komunikaci s podkladovými nativními platformami. V dalších krocích se vytvoří protějšek specifický pro danou platformu pro tento kanál.

  5. Do této složky přidejte 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 je bylo možné zpracovávat napříč platformami pomocí výčtu silného typu. Služba umožňuje základní nativní platformě aktivovat akci, pokud je určená v datové části oznámení. Umožňuje také běžnému kódu retrospektivní kontrolu, zda byla během spuštění aplikace zadána akce, jakmile je Flutter připravena 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 services s 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í 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 Ověření klientů pomocí oddílu klíč rozhraní API.

  7. Přidejte nový soubor do složky lib s 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, jak definovat tajné kódy aplikací. Zástupné hodnoty nahraďte vlastními hodnotami. Měli byste 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 je vyžadován pouze v případě, že jste se rozhodli dokončit Ověření klientů pomocí oddílu klíč 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 main_page.dartnahraďte funkci build 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 do horní části souboru main_page.dart.

    import 'package:push_demo/services/notification_registration_service.dart';
    import 'config.dart';
    
  3. Přidejte do třídy _MainPageState 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 Register a Deregister tlačítka událostí. Volejte odpovídající metody Register/Deregister metody a zobrazte výstrahu, která bude indikovat 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. Nyní v main.dartzajistěte, aby v horní části souboru byly přítomny 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 inicializujete ji.

    final notificationActionService = NotificationActionService();
    
  7. Přidání funkcí pro zpracování zobrazení výstrahy 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, abyste mohli sledovat NotificationActionServiceakceTriggered stream a kontrolovat všechny akce zachycené během spouš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

    Stačí jen předvést příjem a šíření akcí nabízených oznámení. Obvykle se jedná o tiché zpracování, například přechod do konkrétního zobrazení nebo aktualizace některých dat místo zobrazení výstrahy v tomto případě.

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

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

  1. Ovládací prvekKlikněte na ve složce androidu a pak zvolte Otevřít v android Studiu. Pak přepněte do zobrazení Projectu (pokud ještě není).

  2. Vyhledejte dříve stažený soubor google-services.json při nastavování projektu PushDemo vkonzoly Firebase . Potom ho přetáhněte do kořenového adresáře modulu aplikace (androidandroidaplikace).

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

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

  2. Otevřete AndroidManifest.xmla potom přidejte oprávnění INTERNET a READ_PHONE_STATE za prvek aplikace před pravou 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 Studiootevřete soubor build.gradle na úrovni projektu (gradle Scripts>build.gradle (Project: android)). a ujistěte se, že máte cestu ke třídě com.google.gms:google-services v buildscript>závislostech uzlu.

    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

    Nezapomeňte odkazovat na nejnovější verzi podle pokynů uvedených v konzole Firebase při vytváření projektu Android Project.

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

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

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

    Poznámka

    Ujistěte se, že odkazujete na nejnovější verzi podle klientské dokumentace ke cloudovému zasílání zpráv pro Android.

  4. Uložte změny a potom klikněte na tlačítko Synchronizovat nyní (na příkazovém řádku panelu nástrojů) nebo Synchronizovat projekt se soubory Gradle.

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

  1. V Android StudioKlikněte na na com.your_organizationsložku balíčku .pushdemo (aplikacekotlin), v nabídce Nový zvolte Balíček. Jako název zadejte služby a stiskněte klávesu Return.

  2. Ovládací prvek + Klikněte na ve složce služeb, v nabídce New zvolte Kotlin File/Class. Jako název zadejte DeviceInstallationService a stiskněte Return.

  3. Implementujte 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 protějšk specifický pro platformu pro kanál com.<your_organization>.pushdemo/deviceinstallation. Tato možnost byla definována v části Flutter aplikace v DeviceInstallationService.dart. V tomto případě se volání provádí z běžného kódu na nativního hostitele. Nezapomeňte nahradit <your_organization> vlastní organizací bez ohledu na to, kde se 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 s názvem NotificationRegistrationServicepřidejte další Kotlin File/Class 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 protějšk specifický pro platformu pro kanál com.<your_organization>.pushdemo/notificationregistration. To bylo definováno v části Flutter aplikace v NotificationRegistrationService.dart. V tomto případě se volání provádí z nativního hostitele do společného kódu. Znovu se zastarejte o nahrazení <your_organization> vaší vlastní organizací, ať se používá kdekoli.

  5. Do složky služeb s názvem NotificationActionServicepřidejte další Kotlin File/Class. 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 protějšk specifický pro platformu pro kanál 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 nahradit <your_organization> vlastní organizací bez ohledu na to, kde se používá.

  6. Do com přidejte nový kotlinový soubor nebo třída.<your_organization>balíček .pushdemo s názvem PushNotificationsFirebaseMessagingServicea pak implementujte následující kód.

    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 na NotificationActionService pokud je akce zahrnuta do datové části oznámení přijaté v onMessageReceived. Tím se také zavolá refreshRegistration NotificationRegistrationService, když Firebase token znovu vygeneruje přepsáním funkce onNewToken.

    Znovu se postaráme o nahrazení <your_organization> vaší vlastní organizací bez ohledu na to, kde se používá.

  7. V AndroidManifest.xml (app>src>main), přidejte PushNotificationsFirebaseMessagingService na konec 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. Vraťte se zpět do DeviceInstallationService, ujistěte se, že v horní části souboru jsou přítomné následující importy.

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

    Poznámka

    Nahraďte <your_organization> vlastní hodnotou organizace.

  9. Aktualizujte zástupný text, Placeholder_Get_Value_From_FirebaseMessagingService_Implementation získat 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 MainActivity se ujistěte, že jsou v horní části souboru přítomny 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 organizace.

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

    private lateinit var deviceInstallationService: DeviceInstallationService
    
  12. Přidejte funkci s názvem processNotificationActions a zkontrolujte, jestli záměru má další hodnotu s názvem akce. Podmíněně aktivujte tuto akci nebo ji uložte pro pozdější použití, pokud se akce zpracovává během spuš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, že LaunchMode pro MainActivity je nastavená na SingleTop, záměru se odešle do existující instance aktivity prostřednictvím onNew. FunkceIntent místo funkce onCreate, a proto musíte zpracovat příchozí intent v onCreate i funkce onNewIntent.

  14. Přepište funkci onCreate, 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 vlastnosti 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 na 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. Stále v onCreate, volání processNotificationActions na konci funkce. Pro argument launchAction použijte true, který indikuje, že se tato akce zpracovává během spuštění aplikace.

    processNotificationActions(this.intent, true)
    

Poznámka

Aplikaci je nutné znovu zaregistrovat pokaždé, když ji spustíte, a zastavit ji z ladicí relace, abyste mohli pokračovat v přijímání nabízených oznámení.

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

Konfigurace cíle spouštěče a souboru Info.plist

  1. V editoru Visual Studio CodeOvládací prvek Klikněte na ve složce ios a potom zvolte Otevřít v Xcode.

  2. V Xcode klikněte na Runner (xcodeproj v horní části, ne na složku), vyberte Runner cíl a pak Možnosti & podepisování. Pokud je vybraná konfigurace sestavení Všechny, zvolte svůj vývojářský účet protýmu . Ujistěte se, že je zaškrtnutá možnost Automaticky spravovat podepisování a že jsou automaticky vybrány podpisové certifikáty a zřizovací profil.

    Poznámka

    Pokud novou hodnotu zřizovacího profilu nevidíte, zkuste aktualizovat profily podpisové identity tak, že vyberete Xcode>Předvolby>Účet potom výběrem tlačítka Stáhnout ruční profily profily stáhnout.

  3. Klikněte na + Schopnosta vyhledejte nabízená oznámení. tuto funkci přidáte poklikáním na na nabízených oznámení.

  4. Otevřete Info.plist a nastavte minimální systémovou verzi na 13.0.

    Poznámka

    Pro účely tohoto kurzu jsou podporována pouze zařízení se systémem iOS 13.0 a vyššími, ale můžete je rozšířit tak, aby podporovala zařízení se staršími verzemi.

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

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

  1. OvládacíKlikněte na ve složce spouštěče (v projektu Runner) a pak jako název zvolte Nová skupina pomocí Services.

  2. Ovládací prvekKlikněte na ve složce Services a pak zvolte Nový soubor.... Pak zvolte Swift File a klikněte na Další. Jako název zadejte DeviceInstallationService a 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 protějšk specifický pro platformu pro kanál com.<your_organization>.pushdemo/deviceinstallation. Tato možnost byla definována v části Flutter aplikace v DeviceInstallationService.dart. V tomto případě se volání provádí z běžného kódu na nativního hostitele. Nezapomeňte nahradit <your_organization> vlastní organizací bez ohledu na to, kde se 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 služby Services přidejte další Swift File s názvem NotificationRegistrationServicea 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 protějšk specifický pro platformu pro kanál com.<your_organization>.pushdemo/notificationregistration. To bylo definováno v části Flutter aplikace v NotificationRegistrationService.dart. V tomto případě se volání provádí z nativního hostitele do společného kódu. Znovu se zastarejte o nahrazení <your_organization> vaší vlastní organizací, ať se používá kdekoli.

  5. Do složky služby Services s názvem NotificationActionService přidejte další soubor Swift File 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 protějšk specifický pro platformu pro kanál 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 nahradit <your_organization> vlastní organizací bez ohledu na to, kde se používá.

  6. V AppDelegate.swiftpř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ě aktivujte tuto akci nebo ji uložte pro pozdější použití, pokud se akce zpracovává během spuš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 nastavením hodnoty tokenu pro DeviceInstallationService. Potom volejte refreshRegistrationNotificationRegistrationService.

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

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

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

    Poznámka

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

  11. V didFinishLaunchingWithOptionsvytvořte instancideviceInstallationService , notificationRegistrationServicea notificationActionService proměnných.

    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žádejte o autorizaci a zaregistrujte 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 didFinishLaunchingWithOptions funkce. Předejte výsledný objekt userInfo a pro argument launch Action 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)
    }
    

Otestová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 postman.

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

    https://<app_name>.azurewebsites.net/api/notifications/requests
    
  3. Pokud jste se rozhodli dokončit Ověření klientů pomocí oddílu klíč rozhraní API, nezapomeňte nakonfigurovat hlavičky požadavku tak, aby zahrnovaly klíč rozhraní APIkey hodnotu.

    Klíč Hodnota
    apikey <your_api_key>
  4. Zvolte možnost nezpracované protextu a pak v seznamu možností formátu vyberte JSON a pak do pole se seznamem možností formátu zadejte zástupný symbol JSON:

    {
        "text": "Message from Postman!",
        "action": "action_a"
    }
    
  5. Vyberte tlačítko Code, které je pod tlačítkem Uložit v pravém horním rohu okna. Požadavek by měl vypadat podobně jako v následujícím příkladu při zobrazení HTML (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 android ujistěte se, že v ladicíneběží, nebo pokud je aplikace nasazená spuštěním aplikace, vynuťte zavření aplikace a spusťte ji znovu od spouštěče.

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

  8. Zpátky v 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 Postman zobrazí odpověď 200 OK a že se v aplikaci zobrazí výstraha zobrazující akce ActionA přijatá.

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

  11. Ověřte, že se v 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 aplikace otevře a zobrazila akce ActionA přijatá upozornění.

  13. Zpátky v postmanupravte předchozí text požadavku tak, aby se místo action_a pro hodnotu akce odeslalo tiché oznámení, které určuje action_b.

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

  15. Ověřte, že se v postman zobrazí odpověď 200 OK a že se v aplikaci zobrazuje akce ActionB obdržela místo akce ActionA přijatá.

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

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

Řešení problémů

Žá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 že používá správný port.

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

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

Po spuštění nebo zastavení ladicí relace nepřicházejí oznámení v Androidu

Po spuštění nebo zastavení ladicí relace se ujistěte, že se znovu zaregistrujete. Ladicí program způsobí vygenerování nového tokenu Firebase. Instalace centra oznámení musí být také aktualizována.

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

Ověřte, že nastavujete hlavičku požadavku apikey a tato hodnota odpovídá hlavičce požadavku, 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ě Authentication:ApiKey hodnotu nastavení uživatele používanourozhraní 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 aplikace, které používáte v aplikace API.

Poznámka

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

Pokud jste se rozhodli nedokončíte Ověřovat klienty pomocí oddílu klíč rozhraní API, ujistěte se, že jste u třídy NotificationsController nepoužádali atribut Authorize.

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

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

  • [PUT]https://<api_name>.azurewebsites.net/api/notifications/installations
  • [DELETE]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
  • [DELETE]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čí /. Základní adresa by měla být při místním testování https://<api_name>.azurewebsites.net/ nebo https://localhost:5001/.

Nejde zaregistrovat a zobrazí se chybová zpráva centra oznámení

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

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

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

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

Projděte si oddíly konfigurace specifické pro danou platformu a ujistěte se, že nebyly zmeškané žádné kroky. Zkontrolujte, jestli se pro installation id a token proměnné pro příslušnou platformu řeší vhodné hodnoty.

Nejde vyřešit ID chybové zprávy zařízení

Projděte si oddíly konfigurace specifické pro danou platformu a ujistěte se, že nebyly zmeškané žádné kroky.

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 můžou odesílat a přijímat oznámení.

Pravděpodobně budete muset přizpůsobit příklad použitý v tomto kurzu tak, aby vyhovoval vašemu vlastnímu scénáři. Doporučujeme také implementovat robustnější zpracování chyb, logiku opakování a protokolování.

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