Oktatóanyag: Leküldéses értesítések küldése Flutter-alkalmazásoknak az Azure Notification Hubs használatával háttérszolgáltatáson keresztül
A minta letöltése
Ebben az oktatóanyagban Azure Notification Hubs használatával küld értesítéseket egy Flutter alkalmazásba, amely androidos és iOScéloz meg.
A ASP.NET Core Web API háttérrendszere eszközregisztrációs kezelésére szolgál az ügyfél számára 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.
Ezeket a műveleteket a Notification Hubs SDK-val kezeli a háttérműveletek. Az általános megközelítéssel kapcsolatos további részleteket az Az alkalmazás háttérrendszeréből való regisztráció dokumentációjában talál.
Ez az oktatóanyag végigvezeti a következő lépéseken:
- Leküldéses értesítési szolgáltatások és az Azure Notification Hubs beállítása.
- Hozzon létre egy ASP.NET Core Web API-háttéralkalmazást.
- Platformfüggetlen Flutter-alkalmazás létrehozása.
- A natív Android-projekt konfigurálása leküldéses értesítésekhez.
- A natív iOS-projekt konfigurálása leküldéses értesítésekhez.
- Tesztelje a megoldást.
Előfeltételek
A folytatáshoz a következőkre van szükség:
- Egy Azure-előfizetés, ahol erőforrásokat hozhat létre és kezelhet.
- A Flutter eszközkészlet (az előfeltételekkel együtt).
- Visual Studio Code a Flutter és Dart beépülő modulokkal telepítve.
- Könyvtárfüggőségek kezelésére telepített CocoaPods.
- Az alkalmazás futtatásának lehetősége Android (fizikai vagy emulátoreszközök) vagy iOS (csak fizikai eszközökön).
Android esetén a következő eszközökre van szüksége:
- Egy fejlesztő által feloldott fizikai eszköz vagy emulátor (az API 26-os vagy újabb verzióját futtatja a Google Play Services telepítve).
iOS esetén a következőket kell tennie:
- Aktív Apple Developer-fiók.
- A fejlesztői fiók
(iOS 13.0 vagy újabb rendszert futtató) .fizikai iOS-eszköz - Egy
.p12 fejlesztési tanúsítvány telepítve akulcskarika lehetővé teszi az alkalmazás fizikai eszközönfuttatását.
Jegyzet
Az iOS-szimulátor nem támogatja a távoli értesítéseket, ezért a minta iOS-en való feltárásakor fizikai eszközre van szükség. Az oktatóanyag elvégzéséhez azonban nem kell futtatnia az alkalmazást Android és iOS.
Ebben az első alapelves példában szereplő lépéseket előzetes tapasztalat nélkül is végrehajthatja. Az alábbi szempontokat azonban érdemes ismernie.
- Apple Developer Portal.
- ASP.NET Core.
- Google Firebase Console.
- Microsoft Azure és Leküldéses értesítések küldése iOS-alkalmazásokba az Azure Notification Hubshasználatával.
- Flutter és Dart platformfüggetlen fejlesztéshez.
- Kotlin és Swift androidos és iOS natív fejlesztéshez.
A megadott lépések a macOS
Leküldéses értesítési szolgáltatások és az Azure Notification Hub beállítása
Ebben a szakaszban Firebase Cloud Messaging (FCM) és Apple Push Notification Services (APNS). 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
Jelentkezzen be a Firebase konzol. Hozzon létre egy új Firebase-projektet, amely PushDemoprojektnévként.
Jegyzet
A rendszer egyedi nevet hoz létre Önnek. Alapértelmezés szerint ez a megadott név kisbetűs változatából és egy kötőjellel elválasztott generált számból áll. Ezt módosíthatja, ha azt szeretné, hogy az továbbra is globálisan egyedi legyen.
A projekt létrehozása után válassza a Firebase hozzáadása androidos alkalmazáshozlehetőséget.
Az Firebase hozzáadása androidos alkalmazáshoz lapon hajtsa végre az alábbi lépéseket.
Az Android-csomagnév, adja meg a csomag nevét. Például:
com.<organization_identifier>.<package_name>
.Válassza Alkalmazás regisztrálásalehetőséget.
Válassza a Letöltés google-services.jsonlehetőséget. Ezután mentse a fájlt egy helyi mappába későbbi használatra, és válassza a Továbblehetőséget.
Válassza Következőlehetőséget.
Válassza a Tovább a konzolra
Jegyzet
Ha a
Tovább a konzolra gomb nincs engedélyezve, a telepítés ellenőrzésénekellenőrzése miatt válassza Hagyja ki ezt a lépést .
A Firebase konzolon válassza ki a projekt fogaskerékét. Ezután válassza Projektbeállításoklehetőséget.
kiválasztása
Jegyzet
Ha még nem töltötte le a google-services.json fájlt, ezen a lapon töltheti le.
Váltson a felhőbeli üzenetkezelés lapra a tetején. Másolja és mentse a kiszolgálókulcsot későbbi használatra. Ezzel az értékkel konfigurálhatja az értesítési központot.
Az 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 az alkalmazást az Apple-ben, és regisztráljon leküldéses értesítésekre is.
Ha még nem regisztrálta az alkalmazást, keresse meg az iOS kiépítési portál
az Apple Developer Centerben. Jelentkezzen be a portálra Apple ID azonosítójával, lépjen Tanúsítványok, Azonosítók & Profilok, majd válassza Azonosítóklehetőséget. Új alkalmazás regisztrálásához kattintson a + gombra. 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áslehetőséget.
Frissítse a következő három értéket az új alkalmazáshoz, majd válassza a Folytatás:
Leírás: Írja be az alkalmazás leíró nevét.
csomagazonosító: Adja meg a com.<organization_identifier>űrlap csomagazonosítóját.<product_name> az alkalmazásterjesztési útmutatójában. Az alábbi képernyőképen a
mobcat
értéket használja a rendszer szervezetazonosítóként, és a PushDemo értéket használja a terméknévként.Leküldéses értesítések: Ellenőrizze a Leküldéses értesítések lehetőséget a Képességek szakaszban.
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áslehetőséget, majd válassza a Regisztrálás lehetőséget az új alkalmazásazonosító megerősítéséhez.
Miután kiválasztotta Regisztráláslehetőséget, az új alkalmazásazonosító sorelemként jelenik meg a Tanúsítványok, Azonosítók & Profilok lapon.
A Tanúsítványok, Azonosítók & Profilok lap Azonosítókterületén keresse meg a létrehozott alkalmazásazonosító sorelemet. Ezután válassza ki a sorát az 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 Apple Push Notification Services (APNS), és kétféleképpen adható meg:
Közvetlenül a Notification Hubba feltölthető p12 leküldéses tanúsítvány létrehozása (az eredeti megközelítés)
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-
1. LEHETŐSÉG: P12 leküldéses tanúsítvány létrehozása, amely közvetlenül feltölthető a Notification Hubba
Mac gépén futtassa a Keychain Access eszközt. A Segédprogramok mappából vagy a Egyéb mappából nyitható meg a launchpaden.
Válassza Kulcskarika-hozzáférési, bontsa ki Tanúsítvány-asszisztens, majd válassza Tanúsítvány kérése hitelesítésszolgáltatótóllehetőséget.
Jegyzet
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ója 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 a Apple Worldwide Developer Relations hitelesítésszolgáltató kulcs van kiválasztva.
Válassza ki a felhasználói e-mail-címét, adja meg a Közös név értéket, győződjön meg arról, hogy megadja a lemezre mentett , majd válassza a Folytatáslehetőséget. Hagyja üresen hitelesítésszolgáltatói e-mail-címet, mert nincs rá szükség.
Adja meg a Tanúsítvány-aláírási kérelem (CSR) fájl nevétMentés máskéntmezőben, jelölje ki a helyet a Hol, majd válassza a Mentéslehetőséget.
Ez a művelet a kiválasztott helyre menti a CSR-fájlt. Az alapértelmezett hely Asztali. Jegyezze meg a fájlhoz választott helyet.
Térjen vissza a
Tanúsítványok, Azonosítók & Profilok lapra az iOS kiépítési portál, görgessen le az ellenőrzött Leküldéses értesítések beállításhoz, majd válassza akonfigurálása a tanúsítvány létrehozásához. Megjelenik Apple Push Notification service TLS/SSL-tanúsítványok ablak. Válassza a Tanúsítvány létrehozása gombot a Fejlesztési TLS/SSL-tanúsítvány szakaszban.
Megjelenik az Új tanúsítvány létrehozása képernyő.
Jegyzet
Ez az oktatóanyag fejlesztési tanúsítványt használ. Ugyanezt a folyamatot használja a rendszer egy é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.
Válassza a Fájl kiválasztásalehetőséget, keresse meg azt a helyet, ahová a CSR-fájltmentette, majd a betöltéshez kattintson duplán a tanúsítvány nevére. Ezután válassza a Folytatáslehetőséget.
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.
A rendszer letölti és menti a tanúsítványt a számítógépre a Letöltések mappában.
Jegyzet
Alapértelmezés szerint a letöltött fejlesztési tanúsítvány neve aps_development.cer.
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, ahogy az az alábbi képen is látható:
Jegyzet
Bár a tanúsítványban szereplő név eltérő lehet, a név előtagja Apple Development iOS Push Services lesz, és a megfelelő csomagazonosítót társítja hozzá.
A Kulcskarika-hozzáférésben Vezérlő + Kattintson a Tanúsítványok kategóriában létrehozott új leküldéses tanúsítványra. Válassza Exportáláslehetőséget, nevezze el a fájlt, jelölje ki a p12 formátumot, majd válassza a Mentéslehetőséget.
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 OK gombra. Jegyezze fel az exportált p12-tanúsítvány fájlnevét és helyét. ApN-ekkel történő hitelesítés engedélyezésére szolgálnak.
Jegyzet
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
Jegyezze fel a következő részleteket:
- alkalmazásazonosító előtag (csapatazonosító)
- csomagazonosító
A tanúsítványok, azonosítók & profilokterületen kattintson Kulcsokelemre.
Jegyzet
Ha már rendelkezik APNS-konfigurált kulccsal, újra használhatja 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 3 lépését 5.
Új kulcs létrehozásához kattintson a + gombra (vagy a Kulcs létrehozása gombra).
Adjon meg egy megfelelő kulcsnevet értéket, majd ellenőrizze az Apple Push Notifications szolgáltatás (APNS) beállítását, majd kattintson a Folytatáselemre, majd a következő képernyőn regisztrálása elemre.
Kattintson a Letöltés elemre, majd helyezze át a p8 fájlt (AuthKey_előtaggal) egy biztonságos helyi könyvtárba, majd kattintson a Készgombra.
Jegyzet
Ügyeljen arra, hogy a p8-fájl biztonságos helyen maradjon (és mentsen 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.
A kulcsokkattintson a létrehozott kulcsra (vagy egy meglévő kulcsra, ha ezt választotta).
Jegyezze fel a kulcsazonosító értékét.
Nyissa meg a p8-tanúsítványt egy tetszőleges alkalmazással, például Visual Studio Code. Jegyezze fel a kulcs értékét (-----BEGIN PRIVATE KEY----- és -----END PRIVATE KEY-----között).
-----BEGIN TITKOS KULCS-----
<key_value>
-----END TITKOS KULCS-----Jegyzet
Ez a token értéke, amelyet később a notification hub konfigurálásához használunk.
A lépések végén a következő információkkal kell rendelkeznie, amelyeket később használhat a Az értesítési központ konfigurálása APNS-adatokkal:
- csapatazonosító (lásd az 1. lépést)
- csomagazonosító (lásd az 1. lépést)
- kulcsazonosító (lásd a 7. lépést)
- token értéke (a 8. lépésben kapott p8 kulcsérték)
Kiépítési profil létrehozása az alkalmazáshoz
Térjen vissza a iOS kiépítési portálra, válassza a Tanúsítványok, Azonosítók & Profiloklehetőséget, a bal oldali menüben válassza Profilok lehetőséget, majd válassza a + új profil létrehozásához. Megjelenik az Új kiépítési profil regisztrálása képernyő.
A kiépítési profil típusaként válassza iOS-alkalmazásfejlesztési a Fejlesztési területen, majd válassza a Folytatáslehetőséget.
Ezután válassza ki a alkalmazásazonosító legördülő listából létrehozott alkalmazásazonosítót, majd válassza a Folytatáslehetőséget.
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áslehetőséget.
Jegyzet
Ez a tanúsítvány nem az előző . lépésben létrehozott leküldéses tanúsítvány. Ez a 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 Developer Portal, Xcode vagy Visual Studiosegítségével hozhatók létre.
Térjen vissza a Tanúsítványok, Azonosítók & Profilok lapra, válassza Profilok lehetőséget a bal oldali menüből, majd válassza a + új profil létrehozásához. Megjelenik az Új kiépítési profil regisztrálása képernyő.
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áslehetőséget.
Ezután válassza ki a teszteléshez használni kívánt eszközöket, majd válassza a Folytatáslehetőséget.
Végül válassza ki a profil nevét Kiépítési profil neve, majd válassza a létrehozása lehetőséget.
Az új kiépítési profil létrehozásakor válassza a Letöltéslehetőséget. Jegyezze meg a mentés helyét.
Keresse meg a kiépítési profil helyét, majd kattintson rá duplán a fejlesztői 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 APNS. P12 leküldéses tanúsítványt vagy jogkivonatalapú hitelesítést is használhat. Ha már létrehozott értesítési központot szeretne használni, ugorjon az 5. lépésre.
Jelentkezzen be az Azure
. Kattintson az Erőforrás létrehozása, majd a Notification Hub, majd a Létrehozáselemre.
Frissítse a következő mezőket, majd kattintson a létrehozása gombra:
BASIC DETAILS
Előfizetés: Válassza ki a cél Előfizetés a legördülő listából
erőforráscsoport: Hozzon létre egy új erőforráscsoport- (vagy válasszon egy meglévőt)NÉVTÉR RÉSZLETEI
Notification Hub Namespace: Adja meg a Notification Hub névterének globálisan egyedi nevét
Jegyzet
Győződjön meg arról, hogy az Új létrehozása beállítás van kiválasztva ehhez a mezőhöz.
NOTIFICATION HUB RÉSZLETEI
Notification Hub: Adjon nevet a Notification Hub
Hely: Válasszon egy megfelelő helyet a legördülő listából
tarifacsomag: Az alapértelmezett ingyenes lehetőség megtartásaJegyzet
Hacsak nem érte el az ingyenes szinten található hubok maximális számát.
A Notification Hub kiépítése után keresse meg az erőforrást.
Lépjen az új Notification Hub.
Válassza hozzáférési szabályzatok a listából (a MANAGEterületen).
Jegyezze fel a házirend neve értékeket a hozzájuk tartozó kapcsolati sztring értékekkel együtt.
A Notification Hub konfigurálása APNS-adatokkal
Az Notification Servicesterületen válassza Apple, majd kövesse a megfelelő lépéseket az Tanúsítvány létrehozása a Notification Hubshoz szakaszban korábban választott módszer alapján.
Jegyzet
Az Éles csak akkor használja alkalmazásmódhoz, csak akkor, 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
Válassza Tanúsítványlehetőséget.
Válassza ki a fájl ikont.
Jelölje ki a korábban exportált .p12 fájlt, majd válassza a Megnyitáslehetőséget.
Szükség esetén adja meg a megfelelő jelszót.
Válassza Tesztkörnyezet módot.
Válassza Mentéslehetőséget.
2. LEHETŐSÉG: Jogkivonatalapú hitelesítés használata
Válassza Tokenlehetőséget.
Adja meg a korábban beszerzett alábbi értékeket:
- kulcsazonosító
- csomagazonosító
- csapatazonosító
- token
Válassza Tesztkörnyezetlehetőséget.
Válassza Mentéslehetőséget.
Az értesítési központ konfigurálása FCM-adatokkal
- Válassza Google (GCM/FCM) a bal oldali menü Beállítások szakaszában.
- Adja meg a kiszolgálókulcsot, feljegyzett Google Firebase Console.
- Válassza mentése az eszköztáron lehetőséget.
ASP.NET Core Web API háttéralkalmazás létrehozása
Ebben a szakaszban a ASP.NET Core Web API háttérrendszerét hozza létre eszközregisztrációs kezeléséhez és az értesítések Flutter mobilalkalmazásba való küldéséhez.
Webes projekt létrehozása
A Visual Studio
válassza Fájl Új megoldás lehetőséget.Válassza .NET Core>App>ASP.NET Core>API>Nextlehetőséget.
Az
Az új ASP.NET Core Web API párbeszédpanelen válassza.NET Core 3.1 lehetőséget.Target Framework Adja meg PushDemoApi a projektnév, majd válassza a létrehozása lehetőséget.
Indítsa el a hibakeresést (parancs + Enter) a sablonalapú alkalmazás teszteléséhez.
Jegyzet
A sablonalapú alkalmazás úgy van konfigurálva, hogy a WeatherForecastController használja a launchUrl. Ez Tulajdonságok>launchSettings.jsonbeállításban van beállítva.
Ha a rendszer egy érvénytelen fejlesztési tanúsítványt kap, üzenet jelenik meg:
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 adjon meg jelszót a tanúsítványhoz és a kulcskarika jelszavához.
Kattintson Igen gombra, amikor a rendszer Az új tanúsítvány telepítése és megbízhatósága, majd adja meg a kulcskarika jelszavát.
Bontsa ki a Vezérlők mappát, majd törölje WeatherForecastController.cs.
WeatherForecast.cstörlése.
Állítson be helyi konfigurációs értékeket a Secret Manager eszközhasználatával. A titkos kulcsok megoldástól való leválasztása biztosítja, hogy ne kerülnek a forráskontrollba. Nyissa meg Terminál, 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 sztringértékére. A létrehozott egy értesítési központot szakaszban. Ellenkező esetben megkeresheti őket Azure.
NotificationHub:Name:
A Áttekintéstetején található Essentials összefoglalásában Név című témakörben talál.NotificationHub:ConnectionString:
Lásd DefaultFullSharedAccessSignaturehozzáférési szabályzatokJegyzet
Éles helyzetekben a kapcsolati sztring biztonságos tárolásához olyan lehetőségeket tekinthet meg, mint például az Azure KeyVault
. Az egyszerűség kedvéért a titkos kulcsok hozzá lesznek adva az 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 jogkivonatok, de elegendőek lesznek az oktatóanyag céljaira. Az API-kulcsok egyszerűen konfigurálhatók a ASP.NET Köztes szoftver.
Adja hozzá a API-kulcsot a helyi konfigurációs értékekhez.
dotnet user-secrets set "Authentication:ApiKey" <value>
Jegyzet
Cserélje le a helyőrző értékét a sajátjára, és jegyezze fel.
Vezérlő + Kattintson a PushDemoApi projektre, válassza Új mappa lehetőséget a Hozzáadás menüből, majd kattintson hozzáadása Hitelesítésmappanév.
Vezérlő + Kattintson a elemre a Hitelesítési mappában, majd válassza Új fájl... lehetőséget a Hozzáadás menüből.
Válassza az Általános>Üres osztálylehetőséget, adja meg a névApiKeyAuthOptions.cs, majd kattintson Új a következő implementáció hozzáadásához.
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; } } }
Vegyen fel egy másik Üres osztály a Hitelesítési nevű mappába ApiKeyAuthHandler.cs, 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)); } } }
Jegyzet
A Authentication Handler olyan típus, amely implementálja a séma viselkedését, ebben az esetben egy egyéni API-kulcsséma.
Adjon hozzá egy másik Üres osztály a Hitelesítési nevű mappához ApiKeyAuthenticationBuilderExtensions.cs, 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); } } }
Jegyzet
Ez a bővítménymetódus leegyszerűsíti a köztes szoftver konfigurációs kódját Startup.cs így olvashatóbbá és általánosabban követhetővé válik.
A Startup.csfrissítse a ConfigureServices metódust az API Key-hitelesítés konfigurálásához 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); }
Továbbra is Startup.cs, frissítse a konfigurálása metódust, hogy meghívja a UseAuthentication és UseAuthorization bővítménymetódusokat az alkalmazás IApplicationBuilder. Győződjön meg arról, hogy ezek a metódusok UseRouting és 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(); }); }
Jegyzet
A UseAuthentication meghívása regisztrálja a korábban regisztrált hitelesítési sémákat használó köztes szoftvert (ConfigureServices). 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
Az értesítési központ és a Notification Hubs SDK használata háttérműveletekhez egy szolgáltatásba van beágyazva. A szolgáltatás regisztrálva van, és megfelelő absztrakción keresztül érhető el.
Vezérlő + Kattintson a a Függőségek mappára, majd válassza a NuGet-csomagok kezelése...lehetőséget.
Keressen Microsoft.Azure.NotificationHubs, és győződjön meg róla, hogy ellenőrizve van.
Kattintson a Csomagok hozzáadásaelemre, majd kattintson elfogadása gombra, amikor a licencfeltételek elfogadására kéri a rendszer.
Vezérlő + Kattintson a PushDemoApi projektre, válassza Új mappa lehetőséget a Hozzáadás menüben, majd kattintson a hozzáadása Modellekmappanévparancsra.
Vezérlő + Kattintson a Modellek mappára, majd válassza Új fájl... lehetőséget a Hozzáadás menüből.
Válassza
Általános Üres osztály , adja meg aNév PushTemplates.cs , majd kattintsonÚj a következő implementáció hozzáadásához.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)\" }"; } } }
Jegyzet
Ez az osztály tartalmazza az ebben a forgatókönyvben megkövetelt általános és csendes értesítések jogkivonatos értesítési hasznos adatait. A hasznos adatok a telepítési kívül vannak definiálva, hogy lehetővé tegyék a kísérletezést anélkül, hogy frissíteniük kellene a meglévő telepítéseket a szolgáltatáson keresztül. 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 egyéni sablonok.
Adjon hozzá egy másik Üres osztály a Modellek nevű mappához 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>(); } }
Adjon hozzá egy másik Üres osztály a Modellek nevű mappához 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; } } }
Vegyen fel egy másik Üres osztály a Modellek nevű 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; } } }
Adjon hozzá egy új mappát a PushDemoApi projekthez, amelynek neve Services.
Vegyen fel egy Üres felületi a Services nevű mappába INotificationService.cs, 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); } }
Adjon hozzá egy Üres osztályNotificationHubsService.csnevű 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); } } }
Jegyzet
A SendTemplateNotificationAsync
megadott címkekifejezés legfeljebb 20 címke lehet. A legtöbb operátor esetében 6-ra van korlátozva, de ebben az esetben a kifejezés csak az ORS-eket (||) tartalmazza. 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. A Startup.csfrissítse a ConfigureServices metódust, hogy a NotificationHubsService a INotificationServiceegyetlentonos implementációjaként adja hozzá.
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ési API létrehozása
Vezérlő + Kattintson a Vezérlők mappára, majd válassza Új fájl... lehetőséget a Hozzáadás menüből.
Válassza ASP.NET Core>Web API Controller Class, adja meg NotificationsController a Név, majd kattintson Újgombra.
Jegyzet
Ha a Visual Studio 2019
követi, válassza a API-vezérlőt olvasási/írási műveletekkel sablonnal.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;
Frissítse a sablonos vezérlőt úgy, hogy az ControllerBase származik, és az ApiController attribútummal van díszítve.
[ApiController] [Route("api/[controller]")] public class NotificationsController : ControllerBase { // Templated methods here }
Jegyzet
A Vezérlő alaposztály támogatja a nézeteket, de erre ebben az esetben nincs szükség, ezért ControllerBase használható helyette. Ha Visual Studio 2019követ, kihagyhatja ezt a lépést.
Ha az Ügyfelek hitelesítése API-kulcs szakasz használatával végzett, akkor a NotificationsController is fel kell díszítenie az Engedélyezés attribútummal.
[Authorize]
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; }
A launchSettings.json (a Tulajdonságok mappában) módosítsa a launchUrl
weatherforecast
-ról api/notifications-ra, hogy megfeleljen a RegistrationsControllerRoute attribútumban megadott URL-címnek.Kezdje el a hibakeresést (Parancs + Enter) annak ellenőrzéséhez, hogy az alkalmazás működik-e az új NotificationsController, és 401 Jogosulatlan állapotot ad vissza.
Jegyzet
Előfordulhat, hogy a Visual Studio nem indítja el automatikusan az alkalmazást a böngészőben. Mostantól Postman fogja használni az API teszteléséhez.
Egy új
lapon állítsa be a kérést a GETPostman . Adja meg az alábbi címet az applicationUrl helyőrzőhelyett a Tulajdonságok launchSettings.json című témakörben található httpsapplicationUrl .<applicationUrl>/api/notifications
Jegyzet
Az applicationUrl az alapértelmezett profilhozhttps://localhost:5001kell lennie. Ha
IIS- használ (windowsosVisual Studio 2019 alapértelmezés szerint), az iisSettings elemben megadottapplicationUrl kell használnia. Ha a cím helytelen, 404-et kap.Ha a Ügyfelek hitelesítése API-kulcs szakasz használatával történő hitelesítését választotta, mindenképpen konfigurálja a kérés fejléceit úgy, hogy az tartalmazza a apikey értékét.
Kulcs Érték apikey <your_api_key> Kattintson a Küldés gombra.
Jegyzet
200 OK állapotot kell kapnia néhány JSON- tartalommal.
Ha SSL-tanúsítvány-ellenőrzésre figyelmeztetést kap, a Beállításokbeállításban kikapcsolhatja az SSL-tanúsítvány-ellenőrzés kérését Postman.
Cserélje le a NotificationsController.cs sablonalapú osztálymeta-metódusá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ásAzure App Service a háttérszolgáltatás üzemeltetéséhez.
Jelentkezzen be az Azure Portal
. Kattintson Erőforrás létrehozása, majd API-alkalmazás, majd a Létrehozásgombra.
Frissítse a következő mezőket, majd kattintson létrehozása gombra.
alkalmazás neve:
Adjon meg egy globálisan egyedi nevet a API-alkalmazáselőfizetés:
Válassza ki ugyanazt a célt, Előfizetés, amelyben létrehozta az értesítési központot.erőforráscsoport:
Válassza ki ugyanazt a erőforráscsoportot, amelyben létrehozta az értesítési központot.App Service-csomag/hely:
Új App Service-csomag létrehozásaJegyzet
Váltson az alapértelmezett beállításról olyan csomagra, amely SSL- támogatást tartalmaz. Ellenkező esetben meg kell tennie a megfelelő lépéseket a mobilalkalmazás használatakor, hogy megakadályozza http kérelmek 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 egy meglévő erőforrást.A API-alkalmazás kiépítése után keresse meg az erőforrást.
Jegyezze fel a URL- tulajdonságot az Essentials összefoglalásában az Áttekintéstetején. Ez az URL-cím az oktatóanyag későbbi részében használt háttérvégpont.
Jegyzet
Az URL-cím a korábban megadott API-alkalmazásnevet használja,
https://<app_name>.azurewebsites.net
formátummal.Válassza Konfigurációs lehetőséget a listából (a Beállításokterületen).
Az alábbi beállítások mindegyikéhez kattintson az Új alkalmazásbeállítás gombra a Név és egy Értékmegadásához, majd kattintson OKgombra.
Név Érték Authentication:ApiKey
<api_key_value> NotificationHub:Name
<hub_name_value> NotificationHub:ConnectionString
<hub_connection_string_value> Jegyzet
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 szakasz használatával végzett hitelesítést választotta. Éles forgatókönyvek esetén olyan lehetőségeket tekinthet meg, mint például Azure KeyVault. Ezek ebben az esetben alkalmazásbeállításokként lettek hozzáadva az egyszerűség kedvéért.
Az összes alkalmazásbeállítás hozzáadása után kattintson a Mentésgombra, majd Folytassa.
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.
Jegyzet
Az alábbi lépések a Mac Visual Studio. Ha windowsos Visual Studio 2019 követ, a közzétételi folyamat más lesz. Lásd: Közzététel az Azure App Service-ben Windowsrendszeren.
Ha még nem tette meg, módosítsa a konfigurációt Hibakeresési verzióról kiadási.
Vezérlő + Kattintson a PushDemoApi projektre, majd válassza Közzététel az Azure-ban... a Közzététel menüből.
Kövesse a hitelesítési folyamatot, ha a rendszer erre kéri. Használja az előző használt fiókot az API-alkalmazás szakasz létrehozásához.
Válassza ki a közzétételi célként korábban létrehozott Azure App Service API-alkalmazás, majd kattintson a Közzétételgombra.
A varázsló befejezése után közzéteszi az alkalmazást az Azure-ban, majd megnyitja az alkalmazást. Jegyezze fel a URL-, ha még nem tette meg. Ez az URL-cím az oktatóanyag későbbi részében használt háttérvégpont.
A közzétett API érvényesítése
nyisson meg egy új lapot, állítsa be a kérelmet a PUTPostman , és adja meg az alábbi címet. Cserélje le a helyőrzőt az előző a háttérszolgáltatás szakaszában jegyzett alapcímre. https://<app_name>.azurewebsites.net/api/notifications/installations
Jegyzet
Az alapcímnek
https://<app_name>.azurewebsites.net/
formátumban kell lennieHa a Ügyfelek hitelesítése API-kulcs szakasz használatával történő hitelesítését választotta, mindenképpen konfigurálja a kérés fejléceit úgy, hogy az tartalmazza a apikey értékét.
Kulcs Érték apikey <your_api_key> Válassza a Törzsnyers lehetőséget, majd a formátumbeállítások listájában válassza JSON, majd adjon meg néhány helyőrzőt JSON--tartalmat:
{}
Kattintson a Küldésgombra.
Jegyzet
A szolgáltatástól 422 UnprocessableEntity állapotot kell kapnia.
Hajtsa végre ismét az 1–4. lépést, de ezúttal adja meg a kérelmek végpontjának megadását, hogy ellenőrizze, hogy 400 hibás kérés választ kap.
https://<app_name>.azurewebsites.net/api/notifications/requests
Jegyzet
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 egy művelet megadásakor, és az alkalmazás az előtérben van. Ellenkező esetben az értesítések megjelennek az értesítési központban.
Jegyzet
A regisztrációs (és törlési) műveleteket általában az alkalmazás életciklusának megfelelő pontján (vagy talán az első futtatás során) 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 vizsgálható és tesztelhető legyen.
A Flutter-megoldás létrehozása
Nyissa meg a Visual Studio Codeúj példányát.
Nyissa meg a parancskatalógus (Shift + Command + P).
Válassza a Flutter: New Project parancsot, majd nyomja le Enterbillentyűt.
Adja meg a projektnévpush_demo, majd válasszon egy projekthelyet.
Amikor a rendszer erre kéri, válassza a Csomagok lekéréselehetőséget.
Vezérlő + Kattintson a a kotlin mappára (alkalmazás>src>fő), majd válassza a Megjelenítés a Finderbenlehetőséget. Ezután nevezze át a gyermekmappát (a kotlin mappában)
com
,<your_organization>
éspushdemo
névre.Jegyzet
A Visual Studio Code sablon használatakor ezek a mappák alapértelmezés szerint com, példa, <project_name>. Feltételezve, hogy mobcat használja a szervezet, a mappastruktúra indikatív módon a következőképpen jelenik meg:
- kotlin
- Com
- mobcat
- pushdemo
- mobcat
- Com
- kotlin
A Visual Studio Code
androidos app build.gradle applicationId értékét frissítse.Jegyzet
A <your_organization> helyőrzőhöz saját szervezetnevet kell használnia. Ha például a szervezet mobcat használ, com.mobcat.pushdemo.
Frissítse a csomag attribútumát a AndroidManifest.xml fájlokban, src>hibakeresési, src>fő, illetve src>profil alatt. Győződjön meg arról, hogy az értékek megfelelnek az előző lépésben használt applicationId.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.<your_organization>.pushdemo>"> ... </manifest>
Frissítse a
android:label
attribútumot a AndroidManifest.xml fájlban src>főPushDemo. Ezután adja hozzá aandroid:allowBackup
attribútumot közvetlenül aandroid:label
alatt, és állítsa az értékét hamis.<application android:name="io.flutter.app.FlutterApplication" android:label="PushDemo" android:allowBackup="false" android:icon="@mipmap/ic_launcher"> ... </application>
Nyissa meg az alkalmazásszintű build.gradle fájlt (androidos>alkalmazás>build.gradle), majd frissítse a compileSdkVersion (az androidos szakaszból) az API 29használatára. Ezután frissítse a
minSdkVersion éstargetSdkVersion értékeket (adefaultConfig szakaszból) a26 , illetve a 29. Jegyzet
Ebben az oktatóanyagban csak azokat az eszközöket támogatjuk, amelyek API 26-os vagy annál magasabb szintű futnak, azonban kiterjesztheti a régebbi verziókat futtató eszközökre.
Vezérlő + Kattintson a az ios mappára, majd válassza a Megnyitás Xcode-banlehetőséget.
Az Xcode
kattintson a Runner (axcodeproj a tetején, nem a mappára). Ezután válassza a Futó célcsoportot, és válassza az Általános lapot. Ha a Minden összeállítási konfiguráció ki van választva, frissítse a Csomagazonosítócom.<your_organization>.PushDemo
.Jegyzet
A <your_organization> helyőrzőhöz saját szervezetnevet kell használnia. Ha például a szervezet
mobcat használ, aza com.mobcat.PushDemo értékét eredményezi.csomagazonosítójának Kattintson
Info.plist , majd frissítse aCsomag nevét értéket a PushDemoZárja be Xcode, és térjen vissza Visual Studio Code.
Visszatérve Visual Studio Code, nyissa meg pubspec.yaml, 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, amikor a rendszer erre kéri.
dependencies: flutter: sdk: flutter http: ^0.12.1 flutter_secure_storage: ^3.3.3
Terminálterületen módosítsa a könyvtárat az ios mappára (a Flutter-projekthez). Ezután hajtsa végre a pod telepítési parancsot az új podok telepítéséhez (amelyet a flutter_secure_storage csomag megkövetel).
Vezérlő + Kattintson a a lib mappára, majd válassza Új fájl lehetőséget a menüből a main_page.dart fájlnév használatával. 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>[], ) ) ); } }
A main.dart
cserélje le a sablonkó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));
A terminál, buildelje és futtassa az alkalmazást az egyes célplatformokon a sablonalapú alkalmazás eszköz(ek)en való futtatásának teszteléséhez. 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
Vezérlő + Kattintson a a lib mappára, majd válassza Új mappa lehetőséget a menüből, modellek a mappanév.
Vezérlő + Kattintson a modellek mappára, majd a device_installation.dart fájlnév használatával válassza Új fájl lehetőséget a menüből. 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, }; }
Adjon hozzá egy új fájlt a modellekhezpush_demo_action.dart nevű mappához, definiálja az ebben a példában támogatott műveletek felsorolását.
enum PushDemoAction { actionA, actionB, }
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); } }
Jegyzet
A <your_organization> helyőrzőhöz saját szervezetnevet kell használnia. Ha például mobcat a szervezetnél, az MethodChannel a com.mobcat.pushdemo/deviceinstallationnevé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 adatokat. A MethodChannel megkönnyíti a kétirányú aszinkron kommunikációt a mögöttes natív platformokkal. A csatorna platformspecifikus megfelelője a későbbi lépésekben jön létre.
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; } } }
Jegyzet
Ez egy egyszerű mechanizmus az értesítési műveletek kezelésének központosítására, hogy azok platformfüggetlen módon, erősen gépelt számbavétellel kezelhetők legyenek. A szolgáltatás lehetővé teszi, hogy a mögöttes natív platform aktiváljon egy műveletet, ha az értesítés hasznos adataiban meg van adva. Emellett lehetővé teszi, hogy a közös kód visszamenőlegesen ellenőrizze, hogy az alkalmazás indításakor adott-e meg egy műveletet, amint a Flutter készen áll a feldolgozásra. Ha például az alkalmazás elindul, koppintson egy értesítésre az értesítési központból.
Adjon hozzá egy új fájlt a szolgáltatásoknotification_registration_service.dart nevű 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; } } }
Jegyzet
Ez az osztály a DeviceInstallationService használatát és a háttérszolgáltatáshoz érkező 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 a Ügyfelek hitelesítése API-kulcs szakasz használatával végzett.
Adjon hozzá egy új fájlt a
config.dart nevű mappához az alábbi implementációval.lib class Config { static String apiKey = "API_KEY"; static String backendServiceEndpoint = "BACKEND_SERVICE_ENDPOINT"; }
Jegyzet
Ez az alkalmazáskulcsok definiálásának egyszerű módja. Cserélje le a helyőrző értékeket a sajátjára. Ezeket fel kellett volna jegyeznie a háttérszolgáltatás létrehozásakor. Az API-alkalmazás URL-címének
https://<api_app_name>.azurewebsites.net/
kell lennie. Az apiKey tag csak akkor szükséges, ha a Ügyfelek hitelesítése API-kulcs szakasz használatával végzett.Mindenképpen vegye fel ezt a gitignore-fájlba, hogy ne véglegesítse ezeket a titkos kulcsokat a forrásvezérlőben.
Platformfüggetlen felhasználói felület implementálása
A main_page.dartcserélje le a build fü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, ), ], ), ), ); }
Adja hozzá a szükséges importálást a main_page.dart fájl elejéhez.
import 'package:push_demo/services/notification_registration_service.dart'; import 'config.dart';
Adjon hozzá egy mezőt a _MainPageState osztályhoz a NotificationRegistrationServicehivatkozásának tárolásához.
final notificationRegistrationService = NotificationRegistrationService(Config.backendServiceEndpoint, Config.apiKey);
A _MainPageState osztályban implementálja a regisztrálása és Deregister gombjainak a lenyomott eseményekhez. Hívja meg a megfelelő Regisztráljon/Deregister metódusokat, majd jelenítsen meg egy riasztást az eredmény jelzésére.
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(); }, ), ], ); }, ); }
Most main.dart, 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';
Deklaráljon egy változót, amely a NotificationActionService egy példányára mutató hivatkozást tárol, és inicializálja azt.
final notificationActionService = NotificationActionService();
Függvények hozzáadása egy művelet aktiválásakor megjelenő riasztások kezelé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(); }, ), ], ); }, ); }
Frissítse a fő függvényt, hogy megfigyelje a NotificationActionServiceactionTriggered streamet, és ellenőrizze az alkalmazás indításakor rögzített műveleteket.
void main() async { runApp(MaterialApp(home: MainPage(), navigatorKey: navigatorKey,)); notificationActionService.actionTriggered.listen((event) { notificationActionTriggered(event as PushDemoAction); }); await notificationActionService.checkLaunchAction(); }
Jegyzet
Ez egyszerűen a leküldéses értesítési műveletek fogadásának és propagálásának szemléltetése. Ezeket általában csendben kezelik, például egy adott nézetre navigálnak, vagy frissítenek néhány adatot ahelyett, hogy riasztást jelenítenének 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
Vezérlő + Kattintson a az androidos mappára, majd válassza a Megnyitás az Android Studio-ben lehetőséget. Ezután váltson a Project nézetre (ha még nem tette meg).
Keresse meg a korábban letöltött
google-services.json fájlt, amikor beállította aPushDemo projektet a firebase-konzol. Ezután húzza a alkalmazás modul gyökérkönyvtárába (androidos>androidos>alkalmazás).
Összeállítási beállítások és engedélyek konfigurálása
Váltson a
Project nézetre androidos. Nyissa meg a AndroidManifest.xml, majd adja hozzá a INTERNET- és READ_PHONE_STATE engedélyeket az alkalmazás eleme 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
Az Android Studio
nyissa meg a projektszintű build.gradle fájlt (Gradle Scripts build.gradle (Project: android) ). és győződjön meg arról, hogy rendelkezik a "com.google.gms:google-services" osztályúttal abuildscript
>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 // ... } }
Jegyzet
Győződjön meg arról, hogy a Android Projectlétrehozásakor a Firebase Console utasításainak megfelelően a legújabb verzióra hivatkozik.
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 androidos csomópont felett.
// ... // Add the following line: apply plugin: 'com.google.gms.google-services' // Google Services plugin android { // ... }
Ugyanabban a fájlban, a függőségek 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' }
Jegyzet
Győződjön meg arról, hogy a Cloud Messaging Android-ügyfél dokumentációjánakalapján a legújabb verzióra hivatkozik.
Mentse a módosításokat, majd kattintson a Szinkronizálás most gombra (az eszköztár parancssorából), vagy Projekt szinkronizálása Gradle Files.
Leküldéses értesítések kezelése Androidhoz
Az Android Studio
Control Click on thecom. package folder (your_organization .pushdemo app src fő kotlin ), válasszaCsomag lehetőséget azÚj menüből. Adja meg szolgáltatások nevét, majd nyomja le a Returnbillentyűt.Vezérlő + Kattintson a a szolgáltatások mappára, válassza Kotlin-fájl/osztály az Új menüből. Adja meg a DeviceInstallationService nevet, majd nyomja le a Returnbillentyűt.
Implementálja a DeviceInstallationService 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" } }
Jegyzet
Ez az osztály a
com.<your_organization>.pushdemo/deviceinstallation
csatorna platformspecifikus megfelelőjét implementálja. Ezt az alkalmazás Flutter részében definiálták DeviceInstallationService.dart. 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, ahol ezt használja.Ez az osztály egyedi azonosítót biztosít (Secure.AndroidIdhasználatával) az értesítési központ regisztrációs hasznos adatainak részeként.
Vegyen fel egy másik Kotlin-fájl/osztály a szolgáltatások nevű mappába NotificationRegistrationService, 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) } }
Jegyzet
Ez az osztály a
com.<your_organization>.pushdemo/notificationregistration
csatorna platformspecifikus megfelelőjét implementálja. Ezt az alkalmazás Flutter részében definiálták NotificationRegistrationService.dart. Ebben az esetben a hívások a natív gazdagépről a közös kódra kerülnek. Ügyeljen arra, hogy a <your_organization> a saját szervezetére cserélje, bárhol is használják.Vegyen fel egy másik Kotlin-fájl/osztály a szolgáltatások nevű mappába NotificationActionService, 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() } } } }
Jegyzet
Ez az osztály a
com.<your_organization>.pushdemo/notificationaction
csatorna platformspecifikus megfelelőjét implementálja. Ezt az alkalmazás Flutter részében definiálták NotificationActionService.dart. Ebben az esetben mindkét irányban lehet hívást kezdeményezni. Mindenképpen cserélje le a <your_organization> a saját szervezetére, ahol ezt használja.Adjon hozzá egy új
Kotlin-fájl/osztály acom. csomaghoz, amelynek neveyour_organization .pushdemo PushNotificationsFirebaseMessagingService , 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)) } } } }
Jegyzet
Ez az osztály felelős az értesítések kezeléséért, ha az alkalmazás az előtérben fut. Feltételesen meghívja a triggerAction a NotificationActionService, ha egy művelet szerepel a onMessageReceivedértesítési hasznos adatában. Ez meghívja refreshRegistration a NotificationRegistrationService, amikor a Firebase jogkivonat újragenerálódik az onNewToken függvény felülírásával.
Még egyszer, ügyeljen arra, hogy a <your_organization> a saját szervezetére cserélje, bárhol is használják.
Az AndroidManifest.xml (alkalmazás>src>fő) adja hozzá a PushNotificationsFirebaseMessagingService a alkalmazás eleméhez 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>
A DeviceInstallationService
visszafelé győződjön meg arról, hogy a következő importálások találhatók a fájl tetején. package com.<your_organization>.pushdemo import com.<your_organization>.pushdemo.services.PushNotificationsFirebaseMessagingService
Jegyzet
Cserélje le a <your_organization> a saját szervezeti értékére.
Frissítse a helyőrző szöveg Placeholder_Get_Value_From_FirebaseMessagingService_Implementation, hogy lekérje a jogkivonat értékét a PushNotificationFirebaseMessagingService.
fun getDeviceToken() : String { if(!playServicesAvailable) { throw Exception(getPlayServicesError()) } // Get token from the PushNotificationsFirebaseMessagingService.token field. val token = PushNotificationsFirebaseMessagingService.token if (token.isNullOrBlank()) { throw Exception("Unable to resolve token for FCM.") } return token }
MainActivityesetén győződjön meg arról, hogy az alábbi importálások találhatók 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
Jegyzet
Cserélje le a <your_organization> a saját szervezeti értékére.
Adjon hozzá egy változót a DeviceInstallationServicehivatkozásának tárolásához.
private lateinit var deviceInstallationService: DeviceInstallationService
Adjon hozzá egy processNotificationActions nevű függvényt annak ellenőrzéséhez, hogy egy szándék rendelkezik-e műveletnevű 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) } } } }
Felülbírálja a onNewIntent függvényt processNotificationActionsmeghívásához.
override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) processNotificationActions(intent) }
Jegyzet
Mivel a
MainActivity LaunchMode SingleTop értékre van állítva, aSzándék a meglévőTevékenység példányhoz lesznek elküldve aonNe A-függvény függvényt, ezért a bejövőhelyett a szándék kell kezelnie az onCreate ésonNewIntent függvények. Bírálja felül a onCreate függvényt, állítsa a deviceInstallationService a DeviceInstallationServiceúj példányára.
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) flutterEngine?.let { deviceInstallationService = DeviceInstallationService(context, it) } }
Állítsa be a notificationActionService és notificationRegistrationService tulajdonságait PushNotificationFirebaseMessagingServices.
flutterEngine?.let { deviceInstallationService = DeviceInstallationService(context, it) PushNotificationsFirebaseMessagingService.notificationActionService = NotificationActionService(it) PushNotificationsFirebaseMessagingService.notificationRegistrationService = NotificationRegistrationService(it) }
Ugyanabban a függvényben feltételesen hívja meg FirebaseInstanceId.getInstance().instanceId. Implementálja az OnCompleteListener az eredményül kapott token értékének beállításához PushNotificationFirebaseMessagingService, mielőtt meghívja refreshRegistration.
if(deviceInstallationService?.playServicesAvailable) { FirebaseInstanceId.getInstance().instanceId .addOnCompleteListener(OnCompleteListener { task -> if (!task.isSuccessful) return@OnCompleteListener PushNotificationsFirebaseMessagingService.token = task.result?.token PushNotificationsFirebaseMessagingService.notificationRegistrationService?.refreshRegistration() }) }
Még mindig onCreate, hívja meg processNotificationActions a függvény végén. A launchAction argumentum igaz használatával jelezheti, hogy a művelet feldolgozása folyamatban van az alkalmazás indítása során.
processNotificationActions(this.intent, true)
Jegyzet
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
Visual Studio CodeVezérlő + Kattintson a az ios mappára, majd válassza a Megnyitás Xcode-banlehetőséget.
A Xcodekattintson Runner (a xcodeproj a tetején, nem a mappára), majd válassza ki a Runner cél, majd Aláírási & képességek. Ha a Minden buildkonfiguráció ki van választva, válassza ki a fejlesztői fiókját a Csapat. 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.
Jegyzet
Ha nem látja az új kiépítési profil értékét, próbálja meg frissíteni az aláírási identitás profiljait a Xcode>Beállítások>Fiók beállítás kiválasztásával, majd válassza a Manuális profilok letöltése gombot a profilok letöltéséhez.
Kattintson a + Képességelemre, majd keresse meg leküldéses értesítéseket. leküldéses értesítések dupla kattintással kattintson a a funkció hozzáadásához.
Nyissa meg
Info.plist , és állítsaMinimális rendszerverzió 13.0. Jegyzet
Ebben az oktatóanyagban csak az iOS 13.0-s vagy újabb rendszerű eszközök támogatottak, de kiterjesztheti a régebbi verziókat futtató eszközökre.
Nyissa meg Runner.entitlements, és győződjön meg arról, hogy az APS-környezet beállítása fejlesztési.
Leküldéses értesítések kezelése iOS rendszeren
Vezérlő + Kattintson a a Futó mappára (a Runner projekten belül), majd válassza Új csoport a Szolgáltatások használatával.
Vezérlő + Kattintson a a Szolgáltatások mappára, majd válassza Új fájl...lehetőséget. Ezután válassza Swift-fájl, majd kattintson a Továbbgombra. Adja meg a névhez DeviceInstallationService, majd kattintson a létrehozása gombra.
Implementálja DeviceInstallationService.swift 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." } }
Jegyzet
Ez az osztály a
com.<your_organization>.pushdemo/deviceinstallation
csatorna platformspecifikus megfelelőjét implementálja. Ezt az alkalmazás Flutter részében definiálták DeviceInstallationService.dart. 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, ahol ezt használja.Ez az osztály egyedi azonosítót biztosít (a UIDevice.identifierForVendor értékkel) az értesítési központ regisztrációs hasznos adatainak részeként.
Vegyen fel egy másik Swift-fájl a Services nevű mappába NotificationRegistrationService, 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) } }
Jegyzet
Ez az osztály a
com.<your_organization>.pushdemo/notificationregistration
csatorna platformspecifikus megfelelőjét implementálja. Ezt az alkalmazás Flutter részében definiálták NotificationRegistrationService.dart. Ebben az esetben a hívások a natív gazdagépről a közös kódra kerülnek. Ügyeljen arra, hogy a <your_organization> a saját szervezetére cserélje, bárhol is használják.Vegyen fel egy másik Swift-fájl a Services nevű mappába NotificationActionService, 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) } } }
Jegyzet
Ez az osztály a
com.<your_organization>.pushdemo/notificationaction
csatorna platformspecifikus megfelelőjét implementálja. Ezt az alkalmazás Flutter részében definiálták NotificationActionService.dart. Ebben az esetben mindkét irányban lehet hívást kezdeményezni. Mindenképpen cserélje le a <your_organization> a saját szervezetére, ahol ezt használja.Az AppDelegate.swift
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?
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) } } }
Bírálja felül a didRegisterForRemoteNotificationsWithDeviceToken függvényt, amely az DeviceInstallationServicetoken értékét állítja be. Ezután hívja meg refreshRegistration a NotificationRegistrationService.
override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { deviceInstallationService?.token = deviceToken notificationRegistrationService?.refreshRegistration() }
Felülbírálja 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) }
Bírálja felül a didFailToRegisterForRemoteNotificationsWithError függvényt a hiba naplózásához.
override func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print(error); }
Jegyzet
Ez nagyon helyőrző. Az éles forgatókönyvekhez megfelelő naplózást és hibakezelést kell implementálnia.
A didFinishLaunchingWithOptionsfá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)
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() } } } }
Ha a launchOptions tartalmazza a remoteNotification kulcsot, hívja meg processNotificationActions a didFinishLaunchingWithOptions függvény végén. Adja át az eredményül kapott userInfo objektumot, és használja igaz a launchAction argumentumhoz. A igaz érték azt jelzi, hogy a művelet feldolgozása az alkalmazás indításakor történik.
if let userInfo = launchOptions?[.remoteNotification] as? [AnyHashable : Any] { processNotificationActions(userInfo: userInfo, launchAction: true) }
A megoldás tesztelése
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
Nyisson meg egy új lapot Postman.
Állítsa be a kérelmet a POST
, és adja meg a következő címet: https://<app_name>.azurewebsites.net/api/notifications/requests
Ha a Ügyfelek hitelesítése API-kulcs szakasz használatával történő hitelesítését választotta, mindenképpen konfigurálja a kérés fejléceit úgy, hogy az tartalmazza a apikey értékét.
Kulcs Érték apikey <your_api_key> Válassza a Törzsnyers lehetőséget, majd a formátumbeállítások listájában válassza JSON, majd adjon meg néhány helyőrzőt JSON--tartalmat:
{ "text": "Message from Postman!", "action": "action_a" }
Válassza a Kód gombot, amely az ablak jobb felső részén található Mentés gomb alatt található. A kérésnek a következő példához hasonlóan kell kinéznie, amikor HTML- jelenik meg (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" }
Futtassa a PushDemo alkalmazást valamelyik vagy mindkét célplatformon (Android és iOS).
Jegyzet
Ha
Android- tesztel, győződjön meg arról, hogy nem a hibakeresésifut, vagy ha az alkalmazást az alkalmazás futtatásával telepítette, akkor zárja be az alkalmazást, és indítsa újra a indítóból. A PushDemo alkalmazásban koppintson a Regisztrálás gombra.
Vissza Postman, zárja be a Kódrészletek létrehozása ablakot (ha még nem tette meg), majd kattintson a Küldés gombra.
Ellenőrizze, hogy 200 OK választ kap-e Postman, és a riasztás megjelenik az alkalmazásban, amely műveletérkezett.
Zárja be a PushDemo alkalmazást, majd kattintson ismét a Küldés gombra Postman.
Ellenőrizze, hogy 200 OK választ kap-e újra Postman. Ellenőrizze, hogy megjelenik-e értesítés a PushDemo alkalmazás értesítési területén a megfelelő üzenettel.
Koppintson az értesítésre annak megerősítéséhez, hogy megnyitja az alkalmazást, és megjeleníti az riasztáshoz kapott
ActionA-műveletet. Visszatérve Postman, módosítsa az előző kérelem törzsét úgy, hogy az művelet értékének action_a helyett csendes értesítést küldjön, amely action_b ad meg.
{ "action": "action_b", "silent": true }
Ha az alkalmazás továbbra is nyitva van, kattintson a Küldés gombra Postman.
Ellenőrizze, hogy
200 OK választ kap-e , és hogy a riasztás megjelenik az alkalmazásban, amelyPostman kapott ActionB-műveletet.MűveletA művelet helyett Zárja be a PushDemo alkalmazást, majd kattintson ismét a Küldés gombra Postman.
Ellenőrizze, hogy 200 OK választ kap-e Postman, és hogy a csendes értesítés nem jelenik 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 Appteszteli, ellenőrizze, hogy a szolgáltatás fut-e, és üzembe lett helyezve, és hiba nélkül elindult-e.
Győződjön meg arról, hogy helyesen adta meg az alapcímet Postman vagy a mobilalkalmazás konfigurációjában az ügyfélen keresztüli teszteléskor. Az alapcímnek indikatív módon https://<api_name>.azurewebsites.net/
vagy https://localhost:5001/
kell lennie a helyi tesztelés során.
Hibakeresési munkamenet indítása vagy leállítása után nem érkezik értesítés Android rendszeren
Győződjön meg arról, hogy a hibakeresési munkamenet indítása vagy leállítása után újra regisztrál. A hibakereső létrehoz egy új Firebase--jogkivonatot. Az értesítési központ telepítését is frissíteni kell.
401 állapotkód fogadása a háttérszolgáltatástól
Ellenőrizze, hogy a apikey kérelemfejlécet á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 helyi teszteléskor kapja, győződjön meg arról, hogy az ügyfélkonfigurációban megadott kulcsérték megegyezik a Authentication:ApiKey felhasználóbeállítási értékkel, amelyet a APIhasznál.
Ha egy API-alkalmazástesztel, győződjön meg arról, hogy az ügyfélkonfigurációs fájl kulcsértéke megegyezik a Hitelesítés:ApiKey alkalmazásbeállítással, amelyet az API-alkalmazáshasznál.
Jegyzet
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 a Ügyfelek hitelesítése API-kulcs szakasz használatával, győződjön meg arról, hogy nem alkalmazta a Engedélyezés attribútumot a NotificationsController osztályra.
404-alapú állapotkód fogadása a háttérszolgáltatástól
Ellenőrizze, hogy a végpont és a HTTP-kérési módszer helyes-e. A végpontoknak például indikatív módon a következőnek kell lenniük:
-
[PUT]
https://<api_name>.azurewebsites.net/api/notifications/installations
-
[DELETE]
https://<api_name>.azurewebsites.net/api/notifications/installations/<installation_id>
-
[POST]
https://<api_name>.azurewebsites.net/api/notifications/requests
Vagy helyi tesztelés esetén:
-
[PUT]
https://localhost:5001/api/notifications/installations
-
[DELETE]
https://localhost:5001/api/notifications/installations/<installation_id>
-
[POST]
https://localhost:5001/api/notifications/requests
Az ügyfélalkalmazás alapcímének megadásakor győződjön meg arról, hogy az /
végződik. Az alapcímnek indikatív módon https://<api_name>.azurewebsites.net/
vagy https://localhost:5001/
kell lennie a helyi tesztelés során.
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 a Http-válasz állapotkódjának meghatározásához állítson be egy töréspontot a HttpResponseStatusCode tulajdonságértékének vizsgálatához.
Tekintse át az előző hibaelhárítási javaslatokat, ahol lehetséges, az állapotkód alapján.
Állítson be egy töréspontot azokra a sorokra, amelyek az adott API adott állapotkódjait adják vissza. 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 Postman a megfelelő hasznos adatokkal. 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 ne maradjon le a lépésekről. Ellenőrizze, hogy a megfelelő platform installation id
és token
változóihoz megfelelő értékek vannak-e feloldva.
Az eszközhöz tartozó azonosító nem oldható fel hibaüzenet jelenik meg
Tekintse át a platformspecifikus konfigurációs szakaszokat, hogy ne maradjon le a lépésekről.
Kapcsolódó hivatkozások
- Azure Notification Hubs áttekintése
- A Flutter telepítése macOS
- A Flutter telepítése Windows
- Notification Hubs SDK háttérbeli műveletekhez
- Notification Hubs SDK a GitHub
- Regisztrálás alkalmazás-háttérrendszerbeli
- regisztrációkezelési
- Címkék használata
- Egyéni sablonok használata
Következő 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 értesítéseket küldhet és fogadhat.
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.
Visual Studio App Center gyorsan beépíthető a elemzési és diagnosztikai biztosító mobilalkalmazásokba, hogy segítsenek a hibaelhárításban.