Megosztás a következőn keresztül:


Oktatóanyag: Leküldéses értesítések küldése Flutter-alkalmazásokba az Azure Notification Hubs használatával háttérszolgáltatáson keresztül

Minta letöltése A minta letöltése

Ebben az oktatóanyagban az Azure Notification Hubs használatával küld leküldéses értesítéseket egy Androidot és iOS-t célzó Flutter-alkalmazásba.

A ASP.NET Core Webes API-háttérrendszer az ügyfél eszközregisztrációjának kezelésére szolgál a legújabb és legjobb telepítési módszer használatával. A szolgáltatás leküldéses értesítéseket is küld platformfüggetlen módon.

Ezek a műveletek a Notification Hubs SDK-val kezelhetők a háttérműveletekhez. Az általános megközelítéssel kapcsolatos további részletekért tekintse meg a Regisztráció az alkalmazás háttérrendszeréből dokumentációt.

Ez az oktatóanyag végigvezeti az alábbi lépéseket:

Előfeltételek

A lépések követéséhez a következőkre van szükség:

Android esetén a következőkre van szüksége:

  • Egy fejlesztő feloldott egy fizikai eszközt vagy egy emulátort (az API 26-os vagy újabb verzióját futtatva, amelyen telepítve van a Google Play Services).

iOS esetén a következőkre van szükség:

Megjegyzés

Az iOS-szimulátor nem támogatja a távoli értesítéseket, ezért fizikai eszközre van szükség a minta iOS-en való vizsgálatához. Az oktatóanyag elvégzéséhez azonban nem kell futtatnia az alkalmazást Android és iOS rendszeren is.

Az első alapelveket tartalmazó példában szereplő lépéseket előzetes tapasztalat nélkül is követheti. Az alábbi szempontok ismerete azonban hasznos lehet.

A megadott lépések a macOS rendszerre vonatkoznak. Windows rendszeren aziOS-szempontok kihagyásával is követheti a lépéseket.

Leküldéses értesítési szolgáltatások és az Azure Notification Hub beállítása

Ebben a szakaszban a Firebase Cloud Messaging (FCM) és az Apple Push Notification Services (APNS) szolgáltatást állítja be. Ezután létre kell hoznia és konfigurálnia kell egy értesítési központot, hogy működjön ezekkel a szolgáltatásokkal.

Firebase-projekt létrehozása és a Firebase Cloud Messaging engedélyezése Androidhoz

  1. Jelentkezzen be a Firebase-konzolra. Hozzon létre egy új Firebase-projektet, amely a PushDemo nevet adja meg projektnévként.

    Megjegyzés

    A rendszer létrehoz egy egyedi nevet. Alapértelmezés szerint ez a megadott név kisbetűs változata, valamint egy kötőjellel elválasztott generált számból áll. Ezt módosíthatja, ha szeretné, feltéve, hogy az továbbra is globálisan egyedi.

  2. A projekt létrehozása után válassza a Firebase hozzáadása az Android-alkalmazáshoz lehetőséget.

    Firebase hozzáadása androidos alkalmazáshoz

  3. Az Add Firebase to your Android app (Tűzbázis hozzáadása androidos alkalmazáshoz ) lapon hajtsa végre az alábbi lépéseket.

    1. Az Android-csomag neveként adja meg a csomag nevét. Például: com.<organization_identifier>.<package_name>.

      Adja meg a csomag nevét

    2. Válassza az Alkalmazás regisztrálása lehetőséget.

    3. Válassza a Letöltés google-services.json lehetőséget. Ezután mentse a fájlt egy helyi mappába későbbi használatra, és válassza a Tovább gombot.

      Google-services.json letöltése

    4. Kattintson a Tovább gombra.

    5. Válassza a Folytatás konzolra lehetőséget

      Megjegyzés

      Ha a Folytatás konzolra gomb nincs engedélyezve, a telepítés ellenőrzésének ellenőrzése miatt válassza a Lépés kihagyása lehetőséget.

  4. A Firebase konzolon válassza ki a projekthez tartozó fogaskerék elemet. Ezután válassza a Projektbeállítások lehetőséget.

    Projektbeállítások kiválasztása

    Megjegyzés

    Ha még nem töltötte le a google-services.json fájlt, letöltheti erre a lapra.

  5. Váltson a felső Cloud Messaging (Felhőbeli üzenetkezelés ) lapra. Másolja ki és mentse a Kiszolgálókulcsot későbbi használatra. Ezzel az értékkel konfigurálhatja az értesítési központot.

    Kiszolgálókulcs másolása

iOS-alkalmazás regisztrálása leküldéses értesítésekhez

Ha leküldéses értesítéseket szeretne küldeni egy iOS-alkalmazásnak, regisztrálja alkalmazását az Apple-ben, és regisztráljon leküldéses értesítésekre is.

  1. Ha még nem regisztrálta az alkalmazást, keresse meg az iOS kiépítési portálját az Apple Fejlesztői központban. Jelentkezzen be a portálra az Apple ID azonosítójával, lépjen a Tanúsítványok, azonosítók & Profilok elemre, majd válassza az Azonosítók lehetőséget. Kattintson ide + egy új alkalmazás regisztrálásához.

    iOS kiépítési portál alkalmazásazonosítók oldala

  2. Az Új azonosító regisztrálása képernyőn válassza az Alkalmazásazonosítók választógombot. Ezután válassza a Folytatás elemet.

    iOS kiépítési portál – új azonosító regisztrálása oldal

  3. Frissítse a következő három értéket az új alkalmazáshoz, majd válassza a Folytatás lehetőséget:

    • Leírás: Adjon meg egy leíró nevet az alkalmazásnak.

    • Csomagazonosító: Adja meg a com.organization_identifier<> űrlap csomagazonosítóját.<>product_name az alkalmazásterjesztési útmutatóban leírtak szerint. Az alábbi képernyőképen az mobcat érték szervezeti azonosítóként, a PushDemo érték pedig a terméknév.

      iOS Provisioning Portal – Alkalmazásazonosító regisztrálása oldal

    • Leküldéses értesítések: Ellenőrizze a Leküldéses értesítések lehetőséget a Képességek szakaszban.

      Űrlap új alkalmazásazonosító regisztrálásához

      Ez a művelet létrehozza az alkalmazásazonosítót, és kéri, hogy erősítse meg az információkat. Válassza a Folytatás, majd a Regisztráció lehetőséget az új alkalmazásazonosító megerősítéséhez.

      Új alkalmazásazonosító megerősítése

      Miután kiválasztotta a Regisztráció lehetőséget, az új alkalmazásazonosító sorelemként jelenik meg a Tanúsítványok, azonosítók & Profilok lapon.

  4. A Tanúsítványok, azonosítók & Profilok lapon, az Azonosítók területen keresse meg a létrehozott Alkalmazásazonosító sorelemet. Ezután válassza ki a sorát az Alkalmazásazonosító konfigurációjának szerkesztése képernyő megjelenítéséhez.

Tanúsítvány létrehozása a Notification Hubshoz

Tanúsítvány szükséges ahhoz, hogy az értesítési központ működjön az Apple Push Notification Services (APNS) szolgáltatással, és kétféleképpen nyújtható:

  1. P12 leküldéses tanúsítvány létrehozása, amely közvetlenül a Notification Hubra tölthető fel (az eredeti megközelítés)

  2. Jogkivonatalapú hitelesítéshez használható p8-tanúsítvány létrehozása (az újabb és javasolt megközelítés)

Az újabb megközelítés számos előnnyel rendelkezik az APNS tokenalapú (HTTP/2) hitelesítésében dokumentált módon. Kevesebb lépésre van szükség, de adott forgatókönyvekhez is kötelező megadni. A lépések azonban mindkét megközelítéshez meg lettek adva, mivel mindkét módszer az oktatóanyag céljaira fog működni.

1. LEHETŐSÉG: P12 leküldéses tanúsítvány létrehozása, amely közvetlenül a Notification Hubra tölthető fel
  1. Mac gépen futtassa a Keychain Access eszközt. A Utilities mappából vagy a Launchpad Egyéb mappájából nyitható meg.

  2. Válassza a Keychain Access lehetőséget, bontsa ki a Tanúsítványsegéd elemet, majd válassza a Tanúsítvány kérése hitelesítésszolgáltatótól lehetőséget.

    Új tanúsítvány kérése a Keychain Access használatával

    Megjegyzés

    Alapértelmezés szerint a Keychain Access kiválasztja a lista első elemét. Ez akkor lehet probléma, ha a Tanúsítványok kategóriában van, és az Apple Worldwide Developer Relations Hitelesítésszolgáltató nem az első elem a listában. A CSR (tanúsítvány-aláírási kérelem) létrehozása előtt győződjön meg arról, hogy nincs kulcseleme, vagy az Apple Worldwide Developer Relations hitelesítésszolgáltatója kulcs van kiválasztva.

  3. Válassza ki a felhasználó Email címét, adja meg a Common Name (Közös név) értéket, győződjön meg arról, hogy a Mentés lemezre lehetőséget adja meg, majd válassza a Folytatás lehetőséget. Hagyja üresen a hitelesítésszolgáltató Email Cím mezőt, mert nincs rá szükség.

    A tanúsítvány várható adatai

  4. Adja meg a Tanúsítvány-aláírási kérelem (CSR) fájl nevét a Mentés másként területen, válassza ki a helyet a Hol, majd válassza a Mentés lehetőséget.

    A tanúsítvány fájlnevének kiválasztása

    Ez a művelet a CSR-fájlt a kiválasztott helyre menti. Az alapértelmezett hely az Asztal. Jegyezze meg a fájlhoz kiválasztott helyet.

  5. Térjen vissza a Tanúsítványok, azonosítók & Profilok lapra az iOS kiépítési portálon, görgessen le a leküldéses értesítések jelölőnégyzethez, majd válassza a Konfigurálás lehetőséget a tanúsítvány létrehozásához.

    Alkalmazásazonosító szerkesztése lap

  6. Megjelenik az Apple Leküldéses értesítési szolgáltatás TLS/SSL-tanúsítványok ablaka . Válassza a Tanúsítvány létrehozása gombot a Fejlesztési TLS/SSL-tanúsítvány szakaszban.

    Tanúsítvány létrehozása az alkalmazásazonosítóhoz gomb

    Megjelenik az Új tanúsítvány létrehozása képernyő.

    Megjegyzés

    Ez az oktatóanyag fejlesztési tanúsítványt használ. Ugyanezt a folyamatot használja az éles tanúsítvány regisztrálásakor. Csak győződjön meg arról, hogy ugyanazt a tanúsítványtípust használja az értesítések küldésekor.

  7. Válassza a Fájl kiválasztása lehetőséget, keresse meg azt a helyet, ahová a CSR-fájlt mentette, majd kattintson duplán a tanúsítvány nevére a betöltéséhez. Ezután válassza a Folytatás elemet.

  8. Miután a portál létrehozta a tanúsítványt, válassza a Letöltés gombot. Mentse a tanúsítványt, és jegyezze meg a mentés helyét.

    Létrehozott tanúsítvány letöltési lapja

    A rendszer letölti és menti a tanúsítványt a számítógépre a Letöltések mappában.

    Tanúsítványfájl megkeresése a Letöltések mappában

    Megjegyzés

    Alapértelmezés szerint a letöltött fejlesztési tanúsítvány neve aps_development.cer.

  9. Kattintson duplán a letöltött leküldéses tanúsítványra aps_development.cer. Ez a művelet telepíti az új tanúsítványt a kulcskarikán, az alábbi képen látható módon:

    Kulcskarika-hozzáférési tanúsítványok listája új tanúsítványsal

    Megjegyzés

    Bár a tanúsítványban szereplő név eltérő lehet, a név az Apple Development iOS Push Services előtaggal lesz ellátva, és hozzá lesz rendelve a megfelelő csomagazonosító.

  10. A Kulcskarika-hozzáférés területen + kattintson a Tanúsítványok kategóriában létrehozott új leküldéses tanúsítványra . Válassza az Exportálás lehetőséget, nevezze el a fájlt, válassza ki a p12 formátumot, majd válassza a Mentés lehetőséget.

    Tanúsítvány exportálása p12 formátumban

    Dönthet úgy, hogy jelszóval védi a tanúsítványt, de a jelszó megadása nem kötelező. Ha meg szeretné kerülni a jelszó létrehozását, kattintson az OK gombra . Jegyezze fel az exportált p12-tanúsítvány fájlnevét és helyét. Az APN-ekkel történő hitelesítés engedélyezésére szolgálnak.

    Megjegyzés

    A p12-fájl neve és helye eltérhet az oktatóanyagban láthatótól.

2. LEHETŐSÉG: Jogkivonatalapú hitelesítéshez használható p8-tanúsítvány létrehozása
  1. Jegyezze fel a következő részleteket:

    • Alkalmazásazonosító előtag (csapatazonosító)
    • Csomagazonosító
  2. A Tanúsítványok, azonosítók & profilok területen kattintson a Kulcsok elemre.

    Megjegyzés

    Ha már rendelkezik az APNS-hez konfigurált kulccsal, használhatja újra a közvetlenül a létrehozása után letöltött p8-tanúsítványt. Ha igen, figyelmen kívül hagyhatja a 35. lépést.

  3. Kattintson a + gombra (vagy a Kulcs létrehozása gombra) egy új kulcs létrehozásához.

  4. Adjon meg egy megfelelő Kulcsnév értéket, majd ellenőrizze az Apple Push Notifications szolgáltatás (APNS) beállítását, majd kattintson a Folytatás, majd a Regisztráció elemre a következő képernyőn.

  5. Kattintson a Letöltés gombra, majd helyezze át a p8 fájlt ( AuthKey_ előtaggal) egy biztonságos helyi könyvtárba, majd kattintson a Kész gombra.

    Megjegyzés

    Ügyeljen arra, hogy a p8-fájl biztonságos helyen legyen (és mentsen egy biztonsági másolatot). A kulcs letöltése után nem tölthető le újra a kiszolgálópéldány eltávolításakor.

  6. A Kulcsok területen kattintson a létrehozott kulcsra (vagy egy meglévő kulcsra, ha ezt választotta).

  7. Jegyezze fel a Kulcsazonosító értéket.

  8. Nyissa meg a p8-tanúsítványt egy tetszőleges alkalmazásban, például a Visual Studio Code-ban. Jegyezze fel a kulcs értékét ( -----BEGIN PRIVATE KEY----- és -----END PRIVATE KEY----- között).

    -----BEGIN PRIVATE KEY-----
    <key_value>
    -----END PRIVATE KEY-----

    Megjegyzés

    Ez az a tokenérték , amelyet később a Notification Hub konfigurálásához használunk.

Ezeknek a lépéseknek a végén a következő információkkal kell rendelkeznie, amelyeket később használhat az Értesítési központ konfigurálása APNS-adatokkal című cikkben:

  • Csapatazonosító (lásd: 1. lépés)
  • Csomagazonosító (lásd: 1. lépés)
  • Kulcsazonosító (lásd a 7. lépést)
  • Jogkivonat értéke (a 8. lépésben kapott p8 kulcsérték)

Üzembe helyezési profil létrehozása az alkalmazáshoz

  1. Térjen vissza az iOS kiépítési portálra, válassza a Tanúsítványok, azonosítók & Profilok lehetőséget, válassza a profilok lehetőséget a bal oldali menüben, majd válasszon + új profil létrehozásához. Megjelenik az Új kiépítési profil regisztrálása képernyő.

  2. A kiépítési profil típusaként válassza az iOS-alkalmazásfejlesztés lehetőséget a Fejlesztés területen, majd válassza a Folytatás lehetőséget.

    Kiépítési profilok listája

  3. Ezután válassza ki a létrehozott alkalmazásazonosítót az Alkalmazásazonosító legördülő listából, majd válassza a Folytatás lehetőséget.

    Válassza ki az alkalmazásazonosítót

  4. A Tanúsítványok kiválasztása ablakban válassza ki a kódaláíráshoz használt fejlesztési tanúsítványt, majd válassza a Folytatás lehetőséget.

    Megjegyzés

    Ez a tanúsítvány nem az előző lépésben létrehozott leküldéses tanúsítvány. Ez az Ön fejlesztési tanúsítványa. Ha nem létezik, létre kell hoznia, mivel ez az oktatóanyag előfeltétele . A fejlesztői tanúsítványok az Apple Fejlesztői portálon, az Xcode-on vagy a Visual Studióban hozhatók létre.

  5. Térjen vissza a Tanúsítványok, azonosítók & Profilok lapra, válassza a Profilok lehetőséget a bal oldali menüből, majd válassza ki + az új profil létrehozásához. Megjelenik az Új kiépítési profil regisztrálása képernyő.

  6. A Tanúsítványok kiválasztása ablakban válassza ki a létrehozott fejlesztési tanúsítványt. Ezután válassza a Folytatás elemet.

  7. Ezután válassza ki a teszteléshez használni kívánt eszközöket, majd válassza a Folytatás lehetőséget.

  8. Végül válassza ki a profil nevét a Kiépítési profil neve területen, majd válassza a Létrehozás lehetőséget.

    Kiépítési profil nevének kiválasztása

  9. Az új kiépítési profil létrehozásakor válassza a Letöltés lehetőséget. Jegyezze meg a mentés helyét.

  10. Keresse meg a kiépítési profil helyét, majd kattintson rá duplán a fejlesztőgépen való telepítéshez.

Értesítési központ létrehozása

Ebben a szakaszban létrehoz egy értesítési központot, és konfigurálja a hitelesítést az APNS használatával. P12 leküldéses tanúsítványt vagy jogkivonat-alapú hitelesítést is használhat. Ha egy már létrehozott értesítési központot szeretne használni, ugorjon az 5. lépésre.

  1. Jelentkezzen be az Azure-ba.

  2. Kattintson az Erőforrás létrehozása elemre, keresse meg és válassza az Értesítési központ lehetőséget, majd kattintson a Létrehozás gombra.

  3. Frissítse a következő mezőket, majd kattintson a Létrehozás gombra:

    ALAPSZINTŰ RÉSZLETEK

    Előfizetés: Válassza ki a cél-előfizetést a legördülő listából
    Erőforráscsoport: Új erőforráscsoport létrehozása (vagy meglévő kiválasztása)

    NÉVTÉR RÉSZLETEI

    Notification Hub-névtér: Adjon meg egy globálisan egyedi nevet a Notification Hub névteréhez

    Megjegyzés

    Győződjön meg arról, hogy az Új létrehozása lehetőség van kiválasztva ehhez a mezőhöz.

    ÉRTESÍTÉSI KÖZPONT ADATAI

    Értesítési központ: Adja meg a Notification Hub nevét
    Helyen: Válasszon egy megfelelő helyet a legördülő listából
    Tarifacsomag: Az alapértelmezett ingyenes beállítás megtartása

    Megjegyzés

    Hacsak nem érte el az ingyenes szinten található központok maximális számát.

  4. A Notification Hub kiépítése után keresse meg az erőforrást.

  5. Lépjen az új Értesítési központra.

  6. Válassza a Hozzáférési szabályzatok elemet a listából (a KEZELÉS területen).

  7. Jegyezze fel a Szabályzatnév értékeket a hozzájuk tartozó kapcsolati sztringértékekkel együtt.

A Notification Hub konfigurálása APNS-adatokkal

A Notification Services (Értesítési szolgáltatások) területen válassza az Apple lehetőséget, majd kövesse a megfelelő lépéseket az Értesítési központok tanúsítványának létrehozása szakaszban korábban kiválasztott megközelítés alapján.

Megjegyzés

Csak akkor használja az Alkalmazáshoz készült élesüzemmódot , ha leküldéses értesítéseket szeretne küldeni azoknak a felhasználóknak, akik az alkalmazást az áruházból vásárolták.

1. LEHETŐSÉG: .p12 leküldéses tanúsítvány használata

  1. Válassza a Tanúsítvány elemet.

  2. Válassza a fájl ikont.

  3. Jelölje ki a korábban exportált .p12 fájlt, majd válassza a Megnyitás lehetőséget.

  4. Szükség esetén adja meg a megfelelő jelszót.

  5. Válassza a Védőfal módot.

  6. Kattintson a Mentés gombra.

2. LEHETŐSÉG: Jogkivonatalapú hitelesítés használata

  1. Válassza a Jogkivonat lehetőséget.

  2. Adja meg a korábban beszerzett alábbi értékeket:

    • Kulcsazonosító
    • Csomagazonosító
    • Csapatazonosító
    • Token
  3. Válassza a Tesztkörnyezet lehetőséget.

  4. Kattintson a Mentés gombra.

Az értesítési központ konfigurálása FCM-adatokkal

  1. A bal oldali menü Beállítások szakaszában válassza a Google (GCM/FCM) lehetőséget.
  2. Adja meg a Google Firebase-konzolról feljegyzett kiszolgálókulcsot.
  3. Válassza az eszköztár Save (Mentés) elemét.

ASP.NET Core Webes API háttéralkalmazás létrehozása

Ebben a szakaszban a ASP.NET Core Webes API-háttérrendszert hozza létre az eszközregisztráció és az értesítések Flutter mobilalkalmazásba való küldéséhez.

Webes projekt létrehozása

  1. A Visual Studióban válassza a Fájl>új megoldás lehetőséget.

  2. Válassza a .NETCore-alkalmazás>>ASP.NET Core>API>Tovább lehetőséget.

  3. Az új ASP.NET Core Webes API konfigurálása párbeszédpanelen válassza a .NET Core 3.1cél keretrendszerét.

  4. Írja be a PushDemoApi nevet a projektnévhez , majd válassza a Létrehozás lehetőséget.

  5. Indítsa el a hibakeresést (Command + Enter) a sablonalapú alkalmazás teszteléséhez.

    Megjegyzés

    A sablonalapú alkalmazás úgy van konfigurálva, hogy a WeatherForecastControllerthasználja launchUrlként. Ez a Tulajdonságok>launchSettings.json van beállítva.

    Ha a rendszer érvénytelen fejlesztési tanúsítványt talált üzenettel kéri:

    1. Kattintson az Igen gombra a "dotnet dev-certs https" eszköz futtatásához a probléma megoldásához. A "dotnet dev-certs https" eszköz ezután megkéri, hogy adja meg a tanúsítvány jelszavát és a kulcskarika jelszavát.

    2. Kattintson az Igen gombra, amikor a rendszer az új tanúsítvány telepítésére és megbízhatóságára kéri, majd adja meg a kulcskarika jelszavát.

  6. Bontsa ki a Controllers mappát, majd törölje WeatherForecastController.cs.

  7. Törölje WeatherForecast.cs.

  8. Állítson be helyi konfigurációs értékeket a Secret Manager eszközzel. A titkos kódok megoldástól való leválasztása biztosítja, hogy ne kerülnek a forráskontrollba. Nyissa meg a Terminált , majd nyissa meg a projektfájl könyvtárát, és futtassa a következő parancsokat:

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

    Cserélje le a helyőrző értékeket a saját értesítési központ nevére és kapcsolati karakterlánc értékeire. Ezeket az értesítési központ létrehozása szakaszban jegyezte fel. Ellenkező esetben megkeresheti őket az Azure-ban.

    NotificationHub:Name:
    Lásd: Név az Áttekintés tetején található Essentials-összefoglalásban.

    NotificationHub:ConnectionString:
    Lásd: DefaultFullSharedAccessSignature in Access Policies

    Megjegyzés

    Éles forgatókönyvek esetén olyan lehetőségeket tekinthet meg, mint az Azure KeyVault a kapcsolati karakterlánc biztonságos tárolásához. Az egyszerűség kedvéért a titkos kulcsok hozzá lesznek adva a Azure App Service alkalmazásbeállításokhoz.

Ügyfelek hitelesítése API-kulccsal (nem kötelező)

Az API-kulcsok nem olyan biztonságosak, mint a tokenek, de elegendőek az oktatóanyag céljaira. Az API-kulcsok egyszerűen konfigurálhatók a ASP.NET Köztes szoftveren keresztül.

  1. Adja hozzá az API-kulcsot a helyi konfigurációs értékekhez.

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

    Megjegyzés

    Cserélje le a helyőrző értékét a sajátjára, és jegyezze fel.

  2. Ellenőrzés + Kattintson a PushDemoApi projektre, válassza az Új mappa lehetőséget a Hozzáadás menüben, majd kattintson a Hozzáadás hitelesítésselmappanévként elemre.

  3. Ellenőrzés + Kattintson a Hitelesítés mappára, majd válassza az Új fájl... lehetőséget a Hozzáadás menüben.

  4. Válassza az Általános>üres osztály lehetőséget , írja be ApiKeyAuthOptions.cs a Név mezőbe, majd kattintson az Új gombra, és adja hozzá a következő implementációt.

    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. Adjon hozzá egy másik üres osztályt a ApiKeyAuthHandler.cs nevű hitelesítési mappához, majd adja hozzá a következő implementációt.

    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));
            }
        }
    }
    

    Megjegyzés

    A Hitelesítési kezelő egy olyan típus, amely implementálja egy séma viselkedését, ebben az esetben egy egyéni API-kulcsséma.

  6. Adjon hozzá egy másik üres osztályt a ApiKeyAuthenticationBuilderExtensions.cs nevű hitelesítési mappához, majd adja hozzá a következő implementációt.

    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);
            }
        }
    }
    

    Megjegyzés

    Ez a bővítménymetódus leegyszerűsíti a köztes szoftver konfigurációs kódját a Startup.cs így olvashatóbbá és általában könnyebben követhetővé teszi.

  7. A Startup.cs frissítse a ConfigureServices metódust, hogy konfigurálja az API-kulcs hitelesítését a szolgáltatások hívása alatt . AddControllers metódus.

    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. Továbbra is Startup.cs frissítse a Configure metódust, hogy meghívja a UseAuthentication és a UseAuthorization bővítmény metódust az alkalmazás IApplicationBuilderjén. Győződjön meg arról, hogy ezek a metódusok a UseRouting és az alkalmazás előtt vannak meghívva . 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();
        });
    }
    

    Megjegyzés

    A UseAuthentication hívása regisztrálja a korábban regisztrált hitelesítési sémákat használó köztes szoftvereket (a ConfigureServicesből). Ezt minden olyan köztes szoftver előtt meg kell hívni, amely a felhasználók hitelesítésétől függ.

Függőségek hozzáadása és szolgáltatások konfigurálása

ASP.NET Core támogatja a függőséginjektálási (DI) szoftvertervezési mintát, amely az osztályok és függőségeik közötti vezérlés inverziójának (IoC) elérésére szolgáló technika.

Az értesítési központ és a Notification Hubs SDK háttérműveletekhez való használata egy szolgáltatásba van beágyazva. A szolgáltatás regisztrálva van, és megfelelő absztrakción keresztül érhető el.

  1. Ellenőrzés + Kattintson a Függőségek mappára, majd válassza a NuGet-csomagok kezelése... lehetőséget.

  2. Keressen rá a Microsoft.Azure.NotificationHubs kifejezésre , és győződjön meg arról, hogy ellenőrizve van.

  3. Kattintson a Csomagok hozzáadása, majd az Elfogadás gombra, amikor a rendszer a licencfeltételek elfogadására kéri.

  4. Ellenőrzés + Kattintson a PushDemoApi projektre, válassza az Új mappa lehetőséget a Hozzáadás menüben, majd kattintson a Hozzáadásmodellek használatával mappanévként elemre.

  5. Ellenőrzés + Kattintson a Modellek mappára, majd válassza az Új fájl... lehetőséget a Hozzáadás menüben.

  6. Válassza az Általános>üres osztály lehetőséget, adja meg a név PushTemplates.cs, majd kattintson az Új gombra az alábbi implementáció hozzáadása gombra.

    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)\" }";
            }
        }
    }
    

    Megjegyzés

    Ez az osztály az ebben a forgatókönyvben megkövetelt általános és csendes értesítések jogkivonatos értesítési hasznos adatait tartalmazza. A hasznos adatok a telepítésen kívül vannak definiálva, hogy lehetővé tegyék a kísérletezést anélkül, hogy a szolgáltatáson keresztül frissíteni kellene a meglévő telepítéseket. Az oktatóanyag hatókörén kívül esik a telepítések ilyen módon végzett módosításainak kezelése. Éles környezetben fontolja meg az egyéni sablonokat.

  7. Vegyen fel egy másik Üres osztályt a Modellek mappába DeviceInstallation.cs, majd adja hozzá a következő implementációt.

    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. Vegyen fel egy másik Üres osztályt a Models (Modellek ) mappába NotificationRequest.cs, majd adja hozzá a következő implementációt.

    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. Vegyen fel egy másik Üres osztályt a Models (Modellek ) mappába NotificationHubOptions.cs, majd adja hozzá a következő implementációt.

    using System.ComponentModel.DataAnnotations;
    
    namespace PushDemoApi.Models
    {
        public class NotificationHubOptions
        {
            [Required]
            public string Name { get; set; }
    
            [Required]
            public string ConnectionString { get; set; }
        }
    }
    
  10. Adjon hozzá egy új mappát a Szolgáltatások nevű PushDemoApi projekthez.

  11. Adjon hozzá egy üres felületet a INotificationService.cs nevű Services mappához, majd adja hozzá a következő implementációt.

    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. Adjon hozzá egy üres osztályt a NotificationHubsService.cs nevű Services mappához, majd adja hozzá a következő kódot az INotificationService felület implementálásához:

    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);
            }
        }
    }
    

    Megjegyzés

    A SendTemplateNotificationAsync számára megadott címkekifejezés legfeljebb 20 címke lehet. A legtöbb operátor esetében 6-ra van korlátozva, de a kifejezés ebben az esetben csak ARS-eket (||) tartalmaz. Ha a kérelemben több mint 20 címke szerepel, akkor több kérelemre kell felosztani őket. További részletekért tekintse meg az Útválasztási és címkekifejezések dokumentációját.

  13. A Startup.cs frissítse a ConfigureServices metódust, hogy az INotificationService egyetlentonos implementációjaként adja hozzá a NotificationHubsService-t.

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

Az értesítések API létrehozása

  1. Ellenőrzés + Kattintson a Vezérlők mappára, majd válassza az Új fájl... lehetőséget a Hozzáadás menüben.

  2. Válassza a ASP.NET Core>Web API Controller Class (Api-vezérlőosztály) lehetőséget, írja be a Név mezőben a NotificationsController kifejezést, majd kattintson az Új gombra.

    Megjegyzés

    Ha a Visual Studio 2019-et használja, válassza ki az OLVASÁSI/írási műveleteket tartalmazó API-vezérlőt .

  3. Adja hozzá a következő névtereket a fájl elejéhez.

    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. Frissítse a sablonos vezérlőt úgy, hogy a ControllerBase-ből származik, és az ApiController attribútummal van díszítve.

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

    Megjegyzés

    A Controller alaposztály támogatja a nézeteket, de erre ebben az esetben nincs szükség, ezért a ControllerBase használható helyette. Ha a Visual Studio 2019-et követi, kihagyhatja ezt a lépést.

  5. Ha úgy döntött, hogy befejezi az ügyfelek hitelesítése API-kulcs használatával szakaszt , akkor az NotificationsControllert is az Engedélyezés attribútummal kell díszítenie.

    [Authorize]
    
  6. Frissítse a konstruktort, hogy fogadja el az INotificationService regisztrált példányát argumentumként, és rendelje hozzá egy olvasható taghoz.

    readonly INotificationService _notificationService;
    
    public NotificationsController(INotificationService notificationService)
    {
        _notificationService = notificationService;
    }
    
  7. A launchSettings.json -ben (a Tulajdonságok mappában) módosítsa a launchUrl értéket api/notifications értékreweatherforecast, hogy megfeleljen a RegistrationsControllerRoute attribútumban megadott URL-címnek.

  8. Indítsa el a hibakeresést (Command + Enter) annak ellenőrzéséhez, hogy az alkalmazás működik-e az új NotificationsControllerrel , és 401 Jogosulatlan állapotot ad vissza.

    Megjegyzés

    Előfordulhat, hogy a Visual Studio nem indítja el automatikusan az alkalmazást a böngészőben. Mostantól a Postman használatával tesztelheti az API-t.

  9. Egy új Postman lapon állítsa a kérést GET értékre. Írja be az alábbi címet a helyőrző <applicationUrl> helyett a Tulajdonságok>launchSettings.json található https applicationUrl értékre.

    <applicationUrl>/api/notifications
    

    Megjegyzés

    Az applicationUrl értékének az alapértelmezett profilhoz "https://localhost:5001" értéknek kell lennie. Ha IIS-t használ (windowsos Visual Studio 2019-ben alapértelmezés szerint), az iisSettings elemben megadott applicationUrl parancsot kell használnia. Ha a cím helytelen, 404-et kap.

  10. Ha úgy döntött, hogy befejezi az ügyfelek hitelesítése API-kulcs használatával szakaszt , mindenképpen konfigurálja a kérésfejléceket úgy, hogy az tartalmazza az apikey értékét.

    Kulcs Value
    apikey <your_api_key>
  11. Kattintson a Küldés gombra.

    Megjegyzés

    200 OK állapotúnak kell lennie néhány JSON-tartalommal.

    Ha SSL-tanúsítvány-ellenőrzési figyelmeztetést kap, a beállítások között kikapcsolhatja az SSL-tanúsítvány-ellenőrzés Postman kérését.

  12. Cserélje le a NotificationsController.cs sablonalapú osztálymetszetét a következő kódra.

    [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();
    }
    

Az API-alkalmazás létrehozása

Most létrehoz egy API-alkalmazásta Azure App Service a háttérszolgáltatás üzemeltetéséhez.

  1. Jelentkezzen be az Azure Portalra.

  2. Kattintson az Erőforrás létrehozása elemre, keresse meg és válassza az API-alkalmazás lehetőséget, majd kattintson a Létrehozás gombra.

  3. Frissítse a következő mezőket, majd kattintson a Létrehozás gombra.

    Alkalmazás neve:
    Adja meg az API-alkalmazás globálisan egyedi nevét

    Előfizetés:
    Válassza ki ugyanazt a cél-előfizetést , amelyben létrehozta az értesítési központot.

    Erőforráscsoport:
    Válassza ki ugyanazt az erőforráscsoportot , amelyben létrehozta az értesítési központot.

    App Service csomag/hely:
    Új App Service-csomag létrehozása

    Megjegyzés

    Váltson az alapértelmezett beállításról az SSL-támogatást tartalmazó csomagra. Ellenkező esetben meg kell tennie a megfelelő lépéseket, amikor a mobilalkalmazással dolgozik, hogy megakadályozza a HTTP-kérések blokkolását.

    Application Insights:
    Tartsa meg a javasolt beállítást (új erőforrás jön létre ezzel a névvel), vagy válasszon ki egy meglévő erőforrást.

  4. Az API-alkalmazás kiépítése után keresse meg az erőforrást.

  5. Jegyezze fel az URL-tulajdonságot az Áttekintés tetején található Essentials-összefoglalásban. Ez az URL-cím a háttérbeli végpont , amelyet az oktatóanyag későbbi részében fogunk használni.

    Megjegyzés

    Az URL-cím a korábban megadott API-alkalmazásnevet használja a formátummal https://<app_name>.azurewebsites.net.

  6. Válassza a Konfiguráció lehetőséget a listából (a Beállítások területen).

  7. Az alábbi beállítások mindegyikéhez kattintson az Új alkalmazásbeállítás elemre a Név és az Érték megadásához, majd kattintson az OK gombra.

    Name (Név) Value
    Authentication:ApiKey <api_key_value>
    NotificationHub:Name <hub_name_value>
    NotificationHub:ConnectionString <hub_connection_string_value>

    Megjegyzés

    Ezek ugyanazok a beállítások, amelyeket korábban a felhasználói beállításokban definiált. Ezeket át kell tudnia másolni. A Hitelesítés:ApiKey beállítás csak akkor szükséges, ha az ügyfelek hitelesítése API-kulcs használatával szakaszt választotta. Éles forgatókönyvek esetén olyan lehetőségeket tekinthet meg, mint az Azure KeyVault. Ezek az egyszerűség kedvéért alkalmazásbeállításokként lettek hozzáadva ebben az esetben.

  8. Az összes alkalmazásbeállítás hozzáadása után kattintson a Mentés, majd a Folytatás gombra.

A háttérszolgáltatás közzététele

Ezután üzembe helyezi az alkalmazást az API-alkalmazásban, hogy minden eszközről elérhető legyen.

Megjegyzés

Az alábbi lépések a Visual Studio for Mac vonatkoznak. Ha windowsos Visual Studio 2019-et követ, a közzétételi folyamat eltérő lesz. Lásd: Közzététel Azure App Service Windows rendszeren.

  1. Ha még nem tette meg, módosítsa a konfigurációt HibakeresésrőlKiadásra .

  2. Ellenőrzés + Kattintson a PushDemoApi projektre, majd válassza a Közzététel az Azure-ban... lehetőséget a Közzététel menüben.

  3. Kövesse a hitelesítési folyamatot, ha a rendszer erre kéri. Használja az előző létrehozási API-alkalmazás szakaszban használt fiókot.

  4. Jelölje ki a közzétételi célként korábban létrehozott Azure App Service API-alkalmazást a listából, majd kattintson a Közzététel gombra.

A varázsló befejezése után közzéteszi az alkalmazást az Azure-ban, majd megnyitja az alkalmazást. Jegyezze fel az URL-címet , ha még nem tette meg. Ez az URL-cím az oktatóanyag későbbi részében használt háttérbeli végpont .

A közzétett API ellenőrzése

  1. A Postmanben nyisson meg egy új lapot, állítsa a kérést PUT értékre , és adja meg az alábbi címet. Cserélje le a helyőrzőt az előző közzétételi háttérszolgáltatás szakaszában jegyzett alapcímre.

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

    Megjegyzés

    Az alapcím formátuma https://<app_name>.azurewebsites.net/

  2. Ha úgy döntött, hogy befejezi az ügyfelek hitelesítése API-kulcs használatával szakaszt , mindenképpen konfigurálja a kérésfejléceket úgy, hogy az tartalmazza az apikey értékét.

    Kulcs Value
    apikey <your_api_key>
  3. Válassza ki a törzs nyers beállítását, majd a formátumbeállítások listájában válassza a JSON lehetőséget, majd adjon meg néhány helyőrző JSON-tartalmat:

    {}
    
  4. Kattintson a küldése.

    Megjegyzés

    422 UnprocessableEntity állapotot kell kapnia a szolgáltatástól.

  5. Végezze el ismét az 1–4. lépést, de ezúttal adja meg a kérések végpontot annak ellenőrzéséhez, hogy 400 hibás kérésre adott válasz érkezik-e.

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

Megjegyzés

Az API-t még nem lehet érvényes kérelemadatokkal tesztelni, mivel ehhez platformspecifikus információkra lesz szükség az ügyfél-mobilalkalmazásból.

Platformfüggetlen Flutter-alkalmazás létrehozása

Ebben a szakaszban egy Flutter mobilalkalmazást hoz létre, amely platformfüggetlen módon implementálja a leküldéses értesítéseket.

Lehetővé teszi, hogy regisztráljon és töröljön egy értesítési központból a létrehozott háttérszolgáltatáson keresztül.

Riasztás jelenik meg, ha egy művelet meg van adva, és az alkalmazás az előtérben van. Ellenkező esetben az értesítések megjelennek az Értesítési központban.

Megjegyzés

A regisztrációs (és deregisztrációs) műveleteket általában az alkalmazás életciklusának megfelelő pontján (vagy az első futtatási folyamat részeként) hajtaná végre explicit felhasználói regisztráció/regisztráció törlése nélkül. Ez a példa azonban explicit felhasználói bevitelt igényel, hogy a funkció könnyebben megvizsgálható és tesztelhető legyen.

A Flutter-megoldás létrehozása

  1. Nyisson meg egy új Visual Studio Code-példányt.

  2. Nyissa meg a parancskatalógust (Shift + Command + P).

  3. Válassza a Flutter: New Project parancsot, majd nyomja le az Enter billentyűt.

  4. Adja meg push_demo a Projekt neve mezőben, majd válasszon ki egy projekthelyet.

  5. Amikor a rendszer erre kéri, válassza a Csomagok lekérése lehetőséget.

  6. Ellenőrzés + Kattintson a kotlin mappára (az app>src>main területén), majd válassza a Feltárás a Finderben lehetőséget. Ezután nevezze át a gyermekmappát (a kotlin mappa alatt) a következőre: com, <your_organization>, és pushdemo .

    Megjegyzés

    A Visual Studio Code sablon használatakor ezek a mappák alapértelmezés szerint com-ra vannak kapcsolva, <például project_name>. Feltételezve, hogy a mobcat a szervezethez van használva, a mappastruktúra indikatív módon jelenik meg:

    • kotlin
      • Com
        • mobcat
          • pushdemo
  7. A Visual Studio Code-ban frissítse az applicationId értéket az androidos>alkalmazás>build.gradle fájljában a következőre: com.<your_organization>.pushdemo.

    Megjegyzés

    A your_organization> helyőrzőhöz< saját szervezetnevet kell használnia. Ha például a mobcatet használja a szervezetként, az a com.mobcat.pushdemocsomagnév-értékét eredményezi.

  8. Frissítse a csomagattribútumot a AndroidManifest.xml fájlokban, az src>hibakeresés, az src>main és az src>profil alatt. Győződjön meg arról, hogy az értékek megegyeznek az előző lépésben használt applicationId azonosítóval .

    <manifest
        xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.<your_organization>.pushdemo>">
        ...
    </manifest>
    
  9. Frissítse az attribútumot a android:labelAndroidManifest.xmlfájlban az src>main alatt a PushDemo fájlra. Ezután adja hozzá az attribútumot közvetlenül a android:allowBackup alatt android:label, és állítsa az értékét hamis értékre.

    <application
        android:name="io.flutter.app.FlutterApplication"
        android:label="PushDemo"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher">
        ...
    </application>
    
  10. Nyissa meg az alkalmazásszintű build.gradle fájlt (android>app>build.gradle), majd frissítse a compileSdkVersion fájlt (az android szakaszból) az API 29 használatára. Ezután frissítse a minSdkVersion és a targetSdkVersion értékeket (a defaultConfig szakaszból) a 26-os és a 29-es értékre.

    Megjegyzés

    Ebben az oktatóanyagban csak a 26. és újabb SZINTŰ API-t futtató eszközök támogatottak, de kiterjesztheti a régebbi verziókat futtató eszközökre.

  11. Ellenőrzés + Kattintson az ios mappára, majd válassza a Megnyitás Xcode-ban lehetőséget.

  12. Az Xcode-ban kattintson a Runner (a felső xcodeproj elemre, nem a mappára). Ezután válassza ki a Futó célt, és válassza az Általános lapot. Ha a Minden build konfiguráció van kiválasztva, frissítse a Csomagazonosítót a értékre com.<your_organization>.PushDemo.

    Megjegyzés

    A your_organization> helyőrzőhöz< saját szervezetnevet kell használnia. Ha például a mobcatet használja a szervezetként, az a com.mobcat.PushDemocsomagazonosító-értékét eredményezi.

  13. Kattintson az Info.plist elemre, majd frissítse a Csomagnév értékét PushDemo értékre

  14. Zárja be az Xcode-ot , és térjen vissza a Visual Studio Code-hoz.

  15. A Visual Studio Code-ban nyissa meg a pubspec.yaml fájlt, és adja hozzá a HTTP - és flutter_secure_storageDart-csomagokat függőségként. Ezután mentse a fájlt, és kattintson a Csomagok lekérése elemre, amikor a rendszer erre kéri.

    dependencies:
      flutter:
        sdk: flutter
    
      http: ^0.12.1
      flutter_secure_storage: ^3.3.3
    
  16. A Terminálban módosítsa a könyvtárat az ios mappára (a Flutter-projekthez). Ezután futtassa a pod telepítési parancsát az új podok telepítéséhez (amelyet a flutter_secure_storage csomag igényel).

  17. Ellenőrzés + Kattintson a lib mappára, majd válassza az Új fájl lehetőséget a menüben a main_page.dart fájlnévvel. Ezután adja hozzá a következő kódot.

    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. A main.dart fájlban cserélje le a sablonozott kódot a következőre.

    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. A Terminálban hozza létre és futtassa az alkalmazást az egyes célplatformokon a sablonalapú alkalmazás futtatásának teszteléséhez az eszközön(ok)on. Győződjön meg arról, hogy a támogatott eszközök csatlakoztatva vannak.

    flutter run
    

Platformfüggetlen összetevők implementálása

  1. Ellenőrzés + Kattintson a lib mappára, majd válassza az Új mappa lehetőséget a menüben , és használja a modelleketmappanévként.

  2. Ellenőrzés + Kattintson a Models (Modellek ) mappára, majd válassza az Új fájl lehetőséget a menüben a device_installation.dart fájlnévvel. Ezután adja hozzá a következő kódot.

    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. Adjon hozzá egy új fájlt a push_demo_action.dart nevű modellmappához, amely meghatározza az ebben a példában támogatott műveletek felsorolását.

    enum PushDemoAction {
      actionA,
      actionB,
    }
    
  4. Adjon hozzá egy új mappát a szolgáltatások nevű projekthez, majd adjon hozzá egy új fájlt a device_installation_service.dart nevű mappához az alábbi implementációval.

    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);
      }
    }
    

    Megjegyzés

    A your_organization> helyőrzőhöz< saját szervezetnevet kell használnia. Ha például a mobcatet használja a szervezetként, az a com.mobcat.pushdemo/deviceinstallationMethodChannel nevét eredményezi.

    Ez az osztály a mögöttes natív platformmal együttműködve szerzi be a szükséges eszköztelepítési részleteket. A MethodChannel kétirányú aszinkron kommunikációt tesz lehetővé a mögöttes natív platformokkal. A csatorna platformspecifikus megfelelője a későbbi lépésekben jön létre.

  5. Adjon hozzá egy másik fájlt a notification_action_service.dart nevű mappához az alábbi implementációval.

    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;
        }
      }
    }
    

    Megjegyzés

    Ez egy egyszerű mechanizmus, amellyel központosíthatja az értesítési műveletek kezelését, így azok platformfüggetlen módon kezelhetők egy erősen gépelt enumerálással. A szolgáltatás lehetővé teszi, hogy a mögöttes natív platform aktiváljon egy műveletet, ha meg van adva az értesítés hasznos adatai között. Emellett lehetővé teszi, hogy a közös kód visszamenőlegesen ellenőrizze, hogy egy művelet meg lett-e adva az alkalmazás indításakor, amint a Flutter készen áll a feldolgozásra. Ha például az alkalmazást az értesítési központ értesítésére koppintva indítja el.

  6. Adjon hozzá egy új fájlt a notification_registration_service.dart nevű szolgáltatási mappához az alábbi implementációval.

    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;
        }
      }
    }
    

    Megjegyzés

    Ez az osztály a DeviceInstallationService használatát és a háttérszolgáltatásnak küldött kéréseket foglalja magában a szükséges regisztrációs, regisztráció-törlési és frissítési műveletek végrehajtásához. Az apiKey argumentum csak akkor szükséges, ha az Ügyfelek hitelesítése API-kulcs használatával szakaszt választotta.

  7. Adjon hozzá egy új fájlt a config.dart nevű lib mappához az alábbi implementációval.

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

    Megjegyzés

    Ez egy egyszerű módszer az alkalmazás titkos kulcsának meghatározására. Cserélje le a helyőrző értékeket a saját értékére. Ezeket fel kellett volna jegyeznie a háttérszolgáltatás létrehozásakor. Az API-alkalmazás URL-címének a következőnek kell lennie https://<api_app_name>.azurewebsites.net/: . Az apiKey-tag csak akkor szükséges, ha az Ügyfelek hitelesítése API-kulcs használatával szakaszt választotta.

    Ügyeljen arra, hogy ezt hozzáadja a gitignore-fájlhoz, hogy ne véglegesítse ezeket a titkos kódokat a verziókövetésben.

A platformfüggetlen felhasználói felület implementálása

  1. A main_page.dart fájlban cserélje le a buildfüggvényt a következőre.

    @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. Adja hozzá a szükséges importálásokat a main_page.dart fájl elejéhez .

    import 'package:push_demo/services/notification_registration_service.dart';
    import 'config.dart';
    
  3. Adjon hozzá egy mezőt a _MainPageState osztályhoz a NotificationRegistrationService hivatkozásának tárolásához.

    final notificationRegistrationService = NotificationRegistrationService(Config.backendServiceEndpoint, Config.apiKey);
    
  4. A _MainPageState osztályban implementálja a Regisztráció és regisztráció törlése gomb eseménykezelőit a Megnyomott eseményeken . Hívja meg a megfelelő Register/Deregister metódusokat, majd jelenítsen meg egy riasztást az eredmény jelzéséhez.

    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. Most a main.dart fájlban győződjön meg arról, hogy a következő importálások vannak jelen a fájl tetején.

    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. Deklaráljon egy változót a NotificationActionService egy példányára való hivatkozás tárolásához és inicializálásához.

    final notificationActionService = NotificationActionService();
    
  7. Függvények hozzáadása egy művelet aktiválásakor megjelenő riasztások megjelenítéséhez.

    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. Frissítse a függvényt a NotificationActionServiceactionTriggered stream figyeléséhez, és ellenőrizze, hogy vannak-e az alkalmazás indításakor rögzített műveletek.

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

    Megjegyzés

    Ez egyszerűen a leküldéses értesítési műveletek fogadásának és propagálásának szemléltetésére való. Ezeket általában csendesen kezelik, például egy adott nézetre navigálnak, vagy bizonyos adatokat frissítenek, nem pedig riasztást jelenítenek meg ebben az esetben.

A natív Android-projekt konfigurálása leküldéses értesítésekhez

A Google Services JSON-fájljának hozzáadása

  1. Ellenőrzés + Kattintson az android mappára, majd válassza a Megnyitás az Android Studióban lehetőséget. Ezután váltson a Project nézetre (ha még nem tette meg).

  2. Keresse meg azt a google-services.json fájlt, amely a PushDemo-projektFirebase-konzolon való beállításakor korábban letöltött. Ezután húzza az alkalmazásmodul gyökérkönyvtárába (androidos>androidos>alkalmazás).

Összeállítási beállítások és engedélyek konfigurálása

  1. Váltson a Project nézetre Androidra.

  2. Nyissa meg AndroidManifest.xml, majd adja hozzá az INTERNET és READ_PHONE_STATE engedélyeket az alkalmazáselem után a záró címke előtt.

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

A Firebase SDK-k hozzáadása

  1. Az Android Studióban nyissa meg a projektszintű build.gradle fájlt (Gradle Scripts>build.gradle (Project: android)). és győződjön meg arról, hogy a "com.google.gms:google-services" osztályútvonal szerepel a buildscript>függőségek csomópontban.

    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
        // ...
      }
    }
    

    Megjegyzés

    Győződjön meg arról, hogy az Android-projekt létrehozásakor a Firebase-konzol utasításainak megfelelően a legújabb verzióra hivatkozik.

  2. Az alkalmazásszintű build.gradle fájlban (Gradle Scripts>build.gradle (Modul: alkalmazás)) alkalmazza a Google Services Gradle beépülő modult. Alkalmazza a beépülő modult közvetlenül az android-csomópont felett.

    // ...
    
    // Add the following line:
    apply plugin: 'com.google.gms.google-services'  // Google Services plugin
    
    android {
      // ...
    }
    
  3. Ugyanebben a fájlban, a dependencies csomópontban adja hozzá a cloud messaging Android-kódtár függőségét.

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

    Megjegyzés

    Győződjön meg arról, hogy a Cloud Messaging Android ügyféldokumentációjának megfelelően a legújabb verzióra hivatkozik.

  4. Mentse a módosításokat, majd kattintson a Szinkronizálás most gombra (az eszköztár parancssorából) vagy a Projekt szinkronizálása Gradle-fájlokkal lehetőségre.

Leküldéses értesítések kezelése Android rendszeren

  1. Az Android Studióban a Control + Kattintson a com.your_organization.pushdemo<> csomag mappára (app>src>main>kotlin), és válassza a Csomag lehetőséget az Új menüben. Adja meg a szolgáltatások nevet, majd nyomja le a Return billentyűt.

  2. Ellenőrzés + Kattintson a szolgáltatások mappára, majd az Új menüben válassza a Kotlin-fájl/osztály lehetőséget. Adja meg a DeviceInstallationService nevet, majd nyomja le a Return billentyűt.

  3. Implementálja a DeviceInstallationService szolgáltatást az alábbi kóddal.

    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"
        }
    }
    

    Megjegyzés

    Ez az osztály implementálja a csatorna platformspecifikus megfelelőjét com.<your_organization>.pushdemo/deviceinstallation . Ezt az alkalmazás Flutter részében definiálták a DeviceInstallationService.dartban. Ebben az esetben a hívások a közös kódból a natív gazdagépre kerülnek. Mindenképpen cserélje le <a your_organization> a saját szervezetére, bárhol is használják.

    Ez az osztály egyedi azonosítót biztosít ( Secure.AndroidId használatával) az értesítési központ regisztrációs hasznos adatainak részeként.

  4. Adjon hozzá egy másik Kotlin-fájlt/osztályt a NotificationRegistrationService nevű szolgáltatási mappához, majd adja hozzá a következő kódot.

    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)
        }
    }
    

    Megjegyzés

    Ez az osztály implementálja a csatorna platformspecifikus megfelelőjét com.<your_organization>.pushdemo/notificationregistration . Ezt az alkalmazás Flutter részében definiálták a NotificationRegistrationService.dartban. Ebben az esetben a hívások a natív gazdagépről a közös kódba kerülnek. Itt is ügyeljen arra, hogy a your_organization> a saját szervezetére cserélje<, bárhol is használják.

  5. Adjon hozzá egy másik Kotlin-fájlt/osztályt a NotificationActionService nevű szolgáltatási mappához, majd adja hozzá a következő kódot.

    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()
                }
            }
        }
    }
    

    Megjegyzés

    Ez az osztály implementálja a csatorna platformspecifikus megfelelőjét com.<your_organization>.pushdemo/notificationaction . Ez az alkalmazás Flutter részében volt definiálva a NotificationActionService.dartban. Ebben az esetben mindkét irányban indíthatók hívások. Mindenképpen cserélje le <a your_organization> a saját szervezetére, bárhol is használják.

  6. Adjon hozzá egy új Kotlin-fájlt/-osztályt a com.your_organization.pushdemo<> csomaghoz PushNotificationsFirebaseMessagingService néven, majd implementálja az alábbi kóddal.

    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))
                }
            }
        }
    }
    

    Megjegyzés

    Ez az osztály felelős az értesítések kezeléséért, amikor az alkalmazás az előtérben fut. Feltételesen meghívja a triggerAction függvényt a NotificationActionService szolgáltatásban, ha az onMessageReceived szolgáltatásban kapott értesítési hasznos adat tartalmaz egy műveletet. Ez meghívja a refreshRegistration függvényt is a NotificationRegistrationService szolgáltatásban, amikor a Firebase-jogkivonat újra létrejön az onNewToken függvény felülírásával.

    Még egyszer, vigyázzon, hogy cserélje le <a your_organization> a saját szervezetére, bárhol is használják.

  7. A AndroidManifest.xml (app>src>main) területen adja hozzá a PushNotificationsFirebaseMessagingService elemet az alkalmazáselem aljára a com.google.firebase.MESSAGING_EVENT szándékszűrővel.

    <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. A DeviceInstallationService szolgáltatásba visszatérve győződjön meg arról, hogy a következő importálások vannak jelen a fájl tetején.

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

    Megjegyzés

    Cserélje le <a your_organization> a saját szervezeti értékére.

  9. Frissítse a helyőrző szöveg Placeholder_Get_Value_From_FirebaseMessagingService_Implementation , hogy lekérje a token értékét a PushNotificationFirebaseMessagingService szolgáltatásból.

    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. A MainActivity területen győződjön meg arról, hogy a következő importálások vannak jelen a fájl tetején.

    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
    

    Megjegyzés

    Cserélje le <a your_organization> a saját szervezeti értékére.

  11. Adjon hozzá egy változót a DeviceInstallationService hivatkozásának tárolásához.

    private lateinit var deviceInstallationService: DeviceInstallationService
    
  12. Adjon hozzá egy processNotificationActions nevű függvényt annak ellenőrzéséhez, hogy egy szándék rendelkezik-e egy művelet nevű extra értékkel. Feltételesen aktiválja a műveletet, vagy tárolja későbbi használatra, ha a műveletet az alkalmazás indításakor dolgozzák fel.

     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. Bírálja felül az onNewIntent függvényt a processNotificationActions meghívásához.

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

    Megjegyzés

    Mivel a MainActivity LaunchMode tulajdonsága SingleTop értékre van állítva, a rendszer az onNewIntent függvény helyett az onNewIntent függvényen keresztül küld egy szándékota meglévőtevékenységpéldánynak, így a bejövő szándékot a Létrehozás és az OnNewIntent függvényben is kezelnie kell.

  14. Bírálja felül az onCreate függvényt , állítsa a deviceInstallationService elemet a DeviceInstallationService új példányára.

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        flutterEngine?.let {
            deviceInstallationService = DeviceInstallationService(context, it)
        }
    }
    
  15. Állítsa be a notificationActionService és notificationRegistrationService tulajdonságokat a PushNotificationFirebaseMessagingServices elemen.

    flutterEngine?.let {
      deviceInstallationService = DeviceInstallationService(context, it)
      PushNotificationsFirebaseMessagingService.notificationActionService = NotificationActionService(it)
      PushNotificationsFirebaseMessagingService.notificationRegistrationService = NotificationRegistrationService(it)
    }
    
  16. Ugyanebben a függvényben hívja meg feltételesen a FirebaseInstanceId.getInstance().instanceId parancsot. Az OnCompleteListener implementálásával állítsa be az eredményül kapott tokenértéket a PushNotificationFirebaseMessagingService paraméteren, mielőtt meghívja a refreshRegistration parancsot.

    if(deviceInstallationService?.playServicesAvailable) {
        FirebaseInstanceId.getInstance().instanceId
            .addOnCompleteListener(OnCompleteListener { task ->
                if (!task.isSuccessful)
                    return@OnCompleteListener
    
                PushNotificationsFirebaseMessagingService.token = task.result?.token
                PushNotificationsFirebaseMessagingService.notificationRegistrationService?.refreshRegistration()
            })
    }
    
  17. Továbbra is a Létrehozás területen hívja meg a processNotificationActions metódust a függvény végén. A launchAction argumentumnál használja a true (igaz) értéket, ha azt jelzi, hogy a művelet feldolgozása folyamatban van az alkalmazás indításakor.

    processNotificationActions(this.intent, true)
    

Megjegyzés

A leküldéses értesítések fogadásához minden futtatáskor újra regisztrálnia kell az alkalmazást, és le kell állítania egy hibakeresési munkamenetből.

A natív iOS-projekt konfigurálása leküldéses értesítésekhez

A futó cél és az Info.plist konfigurálása

  1. A Visual StudioCode-ban a Control + Kattintson az ios mappára, majd válassza a Megnyitás Xcode-ban lehetőséget.

  2. Az Xcode-ban kattintson a Runner (az xcodeproj elemre a tetején, nem a mappára), majd válassza ki a Futó célt, majd az Aláírás & képességek lehetőséget. Ha a Minden build konfiguráció van kiválasztva, válassza ki a fejlesztői fiókját a csapat számára. Győződjön meg arról, hogy az "Aláírás automatikus kezelése" beállítás be van jelölve, és az aláíró tanúsítvány és a kiépítési profil automatikusan be van jelölve.

    Megjegyzés

    Ha nem látja az új Kiépítési profil értéket, próbálja meg frissíteni az aláíró identitás profiljait az XcodePreferences> Account (Xcode-beállítások>fiókja) lehetőség kiválasztásával, majd válassza a Manuális profilok letöltése gombot a profilok letöltéséhez.

  3. Kattintson a + Képesség elemre, majd keresse meg a leküldéses értesítéseket. Kattintson duplán a leküldéses értesítésekre a funkció hozzáadásához.

  4. Nyissa meg az Info.plist fájlt , és állítsa a Minimális rendszerverzió13.0 értékre.

    Megjegyzés

    Ebben az oktatóanyagban csak az iOS 13.0-s vagy újabb verzióját futtató eszközök támogatottak, de kiterjesztheti a régebbi verziókat futtató eszközökre.

  5. Nyissa meg a Runner.entitlements fájlt, és győződjön meg arról, hogy az APS-környezet beállítása fejlesztésre van állítva.

Leküldéses értesítések kezelése iOS rendszeren

  1. Ellenőrzés + Kattintson a Runner mappára (a Runner projekten belül), majd válassza az Új csoporta Szolgáltatások használatával nevet.

  2. Ellenőrzés + Kattintson a Szolgáltatások mappára, majd válassza az Új fájl... lehetőséget. Ezután válassza a Swift-fájl lehetőséget, és kattintson a Tovább gombra. Adja meg a DeviceInstallationService nevet, majd kattintson a Létrehozás gombra.

  3. Implementálja a DeviceInstallationService.swift eszközt az alábbi kóddal.

    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."
        }
    }
    

    Megjegyzés

    Ez az osztály implementálja a csatorna platformspecifikus megfelelőjét com.<your_organization>.pushdemo/deviceinstallation . Ezt az alkalmazás Flutter részében definiálták a DeviceInstallationService.dartban. Ebben az esetben a hívások a közös kódból a natív gazdagépre kerülnek. Mindenképpen cserélje le <a your_organization> a saját szervezetére, bárhol is használják.

    Ez az osztály egyedi azonosítót biztosít (az UIDevice.identifierForVendor érték használatával) az értesítési központ regisztrációs hasznos adatainak részeként.

  4. Adjon hozzá egy másik Swift-fájlt a NotificationRegistrationService nevű Services mappához, majd adja hozzá a következő kódot.

    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)
        }
    }
    

    Megjegyzés

    Ez az osztály implementálja a csatorna platformspecifikus megfelelőjét com.<your_organization>.pushdemo/notificationregistration . Ezt az alkalmazás Flutter részében definiálták a NotificationRegistrationService.dartban. Ebben az esetben a hívások a natív gazdagépről a közös kódba kerülnek. Itt is ügyeljen arra, hogy a your_organization> a saját szervezetére cserélje<, bárhol is használják.

  5. Adjon hozzá egy másik Swift-fájlt a NotificationActionService nevű Services mappához, majd adja hozzá a következő kódot.

    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)
            }
        }
    }
    

    Megjegyzés

    Ez az osztály implementálja a csatorna platformspecifikus megfelelőjét com.<your_organization>.pushdemo/notificationaction . Ez az alkalmazás Flutter részében volt definiálva a NotificationActionService.dartban. Ebben az esetben mindkét irányban indíthatók hívások. Mindenképpen cserélje le <a your_organization> a saját szervezetére, bárhol is használják.

  6. Az AppDelegate.swift fájlban adjon hozzá változókat a korábban létrehozott szolgáltatásokra mutató hivatkozás tárolásához.

    var deviceInstallationService : DeviceInstallationService?
    var notificationRegistrationService : NotificationRegistrationService?
    var notificationActionService : NotificationActionService?
    
  7. Adjon hozzá egy processNotificationActions nevű függvényt az értesítési adatok feldolgozásához. Feltételesen aktiválja a műveletet, vagy tárolja későbbi használatra, ha a műveletet az alkalmazás indításakor dolgozzák fel.

    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. Felülbírálja a didRegisterForRemoteNotificationsWithDeviceTokenfüggvényt a DeviceInstallationService tokenértékének beállításával. Ezután hívja meg a refreshRegistration parancsot a NotificationRegistrationService szolgáltatásban.

    override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
      deviceInstallationService?.token = deviceToken
      notificationRegistrationService?.refreshRegistration()
    }
    
  9. Bírálja felül a didReceiveRemoteNotification függvényt , amely átadja a userInfo argumentumot a processNotificationActions függvénynek .

    override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
        processNotificationActions(userInfo: userInfo)
    }
    
  10. Írja felül a didFailToRegisterForRemoteNotificationsWithError függvényt a hiba naplózásához.

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

    Megjegyzés

    Ez nagyon sok helyőrző. Az éles forgatókönyvekhez megfelelő naplózást és hibakezelést kell implementálnia.

  11. A didFinishLaunchingWithOptions fájlban példányosíthatja a deviceInstallationService, notificationRegistrationService és notificationActionService változókat.

    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    
    deviceInstallationService = DeviceInstallationService(withBinaryMessenger: controller.binaryMessenger)
    notificationRegistrationService = NotificationRegistrationService(withBinaryMessenger: controller.binaryMessenger)
    notificationActionService = NotificationActionService(withBinaryMessenger: controller.binaryMessenger)
    
  12. Ugyanebben a függvényben feltételesen kérjen engedélyt, és regisztráljon távoli értesítésekre.

    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. Ha a launchOptions tartalmazza a remoteNotification kulcsot, hívja meg a processNotificationActions parancsot a didFinishLaunchingWithOptions függvény végén. Adja meg az eredményül kapott userInfo objektumot, és használja a true (igaz ) értéket a launchAction argumentumhoz. A valódi érték azt jelzi, hogy a műveletet az alkalmazás indításakor dolgozzák fel.

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

A megoldás teszteléséhez

Mostantól tesztelheti az értesítések küldését a háttérszolgáltatáson keresztül.

Tesztértesítés küldése

  1. Nyisson meg egy új lapon Postman.

  2. A kérelem beállítása POST, és adja meg a következő címre:

    https://<app_name>.azurewebsites.net/api/notifications/requests
    
  3. Ha az ügyfelek hitelesítése API-kulcs használatával szakaszt választotta, mindenképpen konfigurálja úgy a kérésfejléceket, hogy tartalmazzák az apikey értékét.

    Kulcs Value
    apikey <your_api_key>
  4. Válassza ki a törzs nyers beállítását, majd a formátumbeállítások listájában válassza a JSON lehetőséget, majd adjon meg néhány helyőrző JSON-tartalmat:

    {
        "text": "Message from Postman!",
        "action": "action_a"
    }
    
  5. Válassza a Kód gombot, amely az ablak jobb felső sarkában található Mentés gomb alatt található. A kérésnek az alábbi példához hasonlóan kell kinéznie a HTML-hez való megjelenítéskor (attól függően, hogy tartalmazott-e apikey fejlécet):

    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. Futtassa a PushDemo alkalmazást az egyik vagy mindkét célplatformon (Android és iOS).

    Megjegyzés

    Ha Androidon tesztel, győződjön meg arról, hogy nem a Hibakeresésben fut, vagy ha az alkalmazást az alkalmazás futtatásával telepítette, kényszerítse az alkalmazás bezárását, és indítsa újra a indítóból.

  7. A PushDemo alkalmazásban koppintson a Regisztráció gombra.

  8. A Postmanbe visszatérve zárja be a Kódrészletek létrehozása ablakot (ha még nem tette meg), majd kattintson a Küldés gombra.

  9. Ellenőrizze, hogy kap-e 200 OK választ a Postmanben , és a riasztás megjelenik az alkalmazásban, amelyen az ActionA művelet érkezett.

  10. Zárja be a PushDemo alkalmazást, majd kattintson ismét a Küldés gombra a Postmanben.

  11. Ellenőrizze, hogy ismét 200 OK választ kap-e a Postmanben . Ellenőrizze, hogy megjelenik-e értesítés a PushDemo alkalmazás értesítési területén a megfelelő üzenettel.

  12. Koppintson az értesítésre annak megerősítéséhez, hogy megnyitja az alkalmazást, és megjeleníti a kapott ActionA művelet riasztását.

  13. A Postmanben módosítsa az előző kérelemtörzset úgy, hogy csendes értesítést küldjön, amely action_b a műveletértékaction_a helyett.

    {
        "action": "action_b",
        "silent": true
    }
    
  14. Ha az alkalmazás továbbra is nyitva van, kattintson a Küldés gombra a Postmanben.

  15. Ellenőrizze, hogy 200 OK választ kap-e a Postmanben, és hogy a riasztás megjelenik-e az alkalmazásban, amely a kapott ActionA művelet helyett az ActionB műveletet jeleníti meg.

  16. Zárja be a PushDemo alkalmazást, majd kattintson ismét a Küldés gombra a Postmanben.

  17. Ellenőrizze, hogy 200 OK választ kap-e a Postmanben , és hogy a csendes értesítés nem jelenik-e meg az értesítési területen.

Hibaelhárítás

Nincs válasz a háttérszolgáltatástól

Helyi teszteléskor győződjön meg arról, hogy a háttérszolgáltatás fut, és a megfelelő portot használja.

Ha az Azure API-alkalmazáson tesztel, ellenőrizze, hogy fut-e a szolgáltatás, és üzembe lett-e helyezve, és hiba nélkül elindult-e.

Győződjön meg arról, hogy helyesen adta meg az alapcímet a Postmanben vagy a mobilalkalmazás konfigurációjában az ügyfélen keresztüli teszteléskor. Az alapcímnek indikatív módon vagy https://localhost:5001/ helyi teszteléskor kell lenniehttps://<api_name>.azurewebsites.net/.

Nem érkeznek értesítések Androidon a hibakeresési munkamenet elindítása vagy leállítása után

Győződjön meg arról, hogy újra regisztrál egy hibakeresési munkamenet elindítása vagy leállítása után. A hibakereső új Firebase-jogkivonatot hoz létre. Az értesítési központ telepítését is frissíteni kell.

401-alapú állapotkód fogadása a háttérszolgáltatástól

Ellenőrizze, hogy az apikey kérelemfejlécét állítja-e be, és ez az érték megegyezik a háttérszolgáltatáshoz konfigurált értékkel.

Ha ezt a hibát a helyi tesztelés során kapja, győződjön meg arról, hogy az ügyfélkonfigurálásban megadott kulcsérték megegyezik az API által használt Authentication:ApiKey felhasználói beállítás értékkel.

Ha API-alkalmazással tesztel, győződjön meg arról, hogy az ügyfél konfigurációs fájljának kulcsértéke megegyezik az API-alkalmazásban használt Authentication:ApiKey alkalmazásbeállítással.

Megjegyzés

Ha ezt a beállítást a háttérszolgáltatás üzembe helyezése után hozta létre vagy módosította, a szolgáltatás érvénybe lépéséhez újra kell indítania a szolgáltatást.

Ha úgy döntött, hogy nem végzi el az Ügyfelek hitelesítése API-kulcs használatával szakaszt , győződjön meg arról, hogy nem alkalmazta az Authorize attribútumot a NotificationsController osztályra.

404-es állapotkód fogadása a háttérszolgáltatástól

Ellenőrizze, hogy a végpont és a HTTP-kérelem metódusa helyes-e. A végpontoknak például a következőnek kell lenniük:

  • [PUT]https://<api_name>.azurewebsites.net/api/notifications/installations
  • [TÖRLÉS]https://<api_name>.azurewebsites.net/api/notifications/installations/<installation_id>
  • [POST]https://<api_name>.azurewebsites.net/api/notifications/requests

Vagy helyi tesztelés esetén:

  • [PUT]https://localhost:5001/api/notifications/installations
  • [TÖRLÉS]https://localhost:5001/api/notifications/installations/<installation_id>
  • [POST]https://localhost:5001/api/notifications/requests

Amikor megadja az alapcímet az ügyfélalkalmazásban, győződjön meg arról, hogy a végződése egy /. Az alapcímnek indikatív módon vagy https://localhost:5001/ helyi teszteléskor kell lenniehttps://<api_name>.azurewebsites.net/.

Nem lehet regisztrálni, és megjelenik egy értesítési központ hibaüzenete

Ellenőrizze, hogy a teszteszköz rendelkezik-e hálózati kapcsolattal. Ezután határozza meg a Http-válasz állapotkódját úgy, hogy beállít egy töréspontot a HttpResponseStatusCode tulajdonságértékének vizsgálatához.

Ha lehetséges, tekintse át az előző hibaelhárítási javaslatokat az állapotkód alapján.

Állítson be egy töréspontot azokra a sorokra, amelyek ezeket a konkrét állapotkódokat adják vissza a megfelelő API-hoz. Ezután próbálja meg meghívni a háttérszolgáltatást helyi hibakereséskor.

Ellenőrizze, hogy a háttérszolgáltatás a várt módon működik-e a Postmanen keresztül a megfelelő hasznos adatok használatával. Használja a szóban forgó platform ügyfélkódja által létrehozott tényleges hasznos adatokat.

Tekintse át a platformspecifikus konfigurációs szakaszokat, hogy biztosan ne maradjon le a lépésekről. Ellenőrizze, hogy a megfelelő értékek és token változók feloldása installation id folyamatban van-e a megfelelő platformon.

Nem sikerült feloldani az eszköz azonosítóját hibaüzenet jelenik meg

Tekintse át a platformspecifikus konfigurációs szakaszokat, hogy biztosan ne maradjon le a lépésekről.

További lépések

Most már rendelkeznie kell egy alapszintű Flutter-alkalmazással, amely egy háttérszolgáltatáson keresztül csatlakozik egy értesítési központhoz, és képes értesítéseket küldeni és fogadni.

Az oktatóanyagban használt példát valószínűleg a saját forgatókönyvéhez kell igazítania. A robusztusabb hibakezelés, az újrapróbálkozási logika és a naplózás megvalósítása is ajánlott.

A Visual Studio App Center gyorsan beépíthető mobilalkalmazásokba , amelyek elemzéseket és diagnosztikát biztosítanak a hibaelhárítás elősegítéséhez.