Öğretici: Arka uç hizmeti aracılığıyla Azure Notification Hubs kullanarak Flutter uygulamalarına anında iletme bildirimleri gönderme
Bu öğreticide, Android ve iOS'yi hedefleyen flutter uygulamasına anında iletme bildirimleri göndermek için Azure Notification Hubs'ı kullanacaksınız.
ASP.NET Core Web API'sinin arka ucu, en son ve en iyi Yükleme yaklaşımını kullanarak istemcinin cihaz kaydını işlemek için kullanılır. Hizmet ayrıca platformlar arası bir şekilde anında iletme bildirimleri de gönderir.
Bu işlemler arka uç işlemleri için Notification Hubs SDK'sı kullanılarak işlenir. Genel yaklaşım hakkında daha fazla ayrıntı , Uygulama arka ucunuzdan kaydolma belgelerinde verilmiştir.
Bu öğreticide aşağıdaki adımlar izlenir:
- Anında İletme Bildirimi Hizmetleri'ni ve Azure Notification Hubs'ı ayarlayın.
- ASP.NET Core Web API'si arka uç uygulaması oluşturun.
- Platformlar arası flutter uygulaması oluşturma.
- Anında iletme bildirimleri için yerel Android projesini yapılandırın.
- Yerel iOS projesini anında iletme bildirimleri için yapılandırın.
- Çözümü test edin.
Önkoşullar
Birlikte ilerlemek için şunlar gerekir:
- Kaynakları oluşturabileceğiniz ve yönetebileceğiniz bir Azure aboneliği .
- Flutter araç seti (önkoşullarıyla birlikte).
- Flutter ve Dart eklentilerinin yüklü olduğu Visual Studio Code.
- Kitaplık bağımlılıklarını yönetmek için yüklü CocoaPods.
- Uygulamayı Android (fiziksel veya öykünücü cihazları) veya iOS (yalnızca fiziksel cihazlar) üzerinde çalıştırma özelliği.
Android için sahip olmanız gerekenler:
- Geliştiricinin kilidini açan fiziksel cihaz veya öykünücü (Google Play Hizmetleri yüklü api 26 ve üzerini çalıştırıyor).
iOS için sahip olmanız gerekenler:
- Etkin bir Apple Geliştirici Hesabı.
- Geliştirici hesabınıza kayıtlı fiziksel bir iOS cihazı (iOS 13.0 ve üzerini çalıştıran).
- Anahtarlığınıza yüklenmiş bir .p12geliştirme sertifikası, bir uygulamayı fiziksel bir cihazda çalıştırmanıza olanak sağlar.
Not
iOS Simülatörü uzaktan bildirimleri desteklemez ve bu nedenle iOS'ta bu örneği keşfederken fiziksel bir cihaz gerekir. Ancak, bu öğreticiyi tamamlamak için uygulamayı hem Android hem de iOS'ta çalıştırmanız gerekmez.
Bu ilk ilkeler örneğindeki adımları önceden deneyim olmadan izleyebilirsiniz. Ancak, aşağıdaki yönlere aşina olma avantajından yararlanabilirsiniz.
- Apple Geliştirici Portalı.
- ASP.NET Core.
- Google Firebase Konsolu.
- Microsoft Azure ve Azure Notification Hubs kullanarak iOS uygulamalarına anında iletme bildirimleri gönderme.
- Platformlar arası geliştirme için Flutter ve Dart .
- Android ve iOS için Kotlin ve Swift yerel geliştirme.
Sağlanan adımlar macOS'a özeldir. iOS yönlerini atlayarak Windows'u takip etmek mümkündür.
Anında İletme Bildirim Hizmetleri'ni ve Azure Notification Hub'ı ayarlama
Bu bölümde Firebase Cloud Messaging (FCM) ve Apple Anında İletme Bildirimi Hizmetleri'ni (APNS) ayarlamış olacaksınız. Ardından bu hizmetlerle çalışmak için bir bildirim hub'ı oluşturup yapılandırabilirsiniz.
Firebase projesi oluşturma ve Android için Firebase Cloud Messaging'i etkinleştirme
Firebase konsolunda oturum açın. Proje adı olarak PushDemo girerek yeni bir Firebase projesi oluşturun.
Not
Sizin için benzersiz bir ad oluşturulur. Varsayılan olarak bu, sağladığınız adın küçük harfli varyantının yanı sıra tireyle ayrılmış olarak oluşturulan bir sayıdan oluşur. Hala genel olarak benzersiz olması koşuluyla bunu değiştirebilirsiniz.
Projenizi oluşturduktan sonra Android uygulamanıza Firebase Ekle'yi seçin.
Android uygulamanıza Firebase ekle sayfasında aşağıdaki adımları uygulayın.
Android paketi adı için paketiniz için bir ad girin. Örneğin:
com.<organization_identifier>.<package_name>
.Uygulamayı kaydet'i seçin.
google-services.json İndir'i seçin. Ardından dosyayı daha sonra kullanmak üzere yerel bir klasöre kaydedin ve İleri'yi seçin.
İleri'yi seçin.
Konsola devam et'i seçin
Not
Konsoluna devam et düğmesi etkin değilse, yüklemeyi doğrula denetimi nedeniyle Bu adımı atla'yı seçin.
Firebase konsolunda projenizin dişlisini seçin. Ardından Proje Ayarları'nı seçin.
Not
google-services.json dosyasını indirmediyseniz bu sayfadan indirebilirsiniz.
Üst kısımdaki Bulut Mesajlaşması sekmesine geçin. Sunucu anahtarını kopyalayıp daha sonra kullanmak üzere kaydedin. Bildirim hub'ınızı yapılandırmak için bu değeri kullanırsınız.
Anında iletme bildirimleri için iOS uygulamanızı kaydetme
Bir iOS uygulamasına anında iletme bildirimleri göndermek için uygulamanızı Apple'a kaydedin ve anında iletme bildirimlerine kaydolun.
Uygulamanızı henüz kaydettiyseniz Apple Geliştirici Merkezi'ndeki iOS Sağlama Portalı'na göz atın. Apple kimliğiniz ile portalda oturum açın, Sertifikalar, Tanımlayıcılar & Profiller'e gidin ve Tanımlayıcılar'ı seçin. Yeni bir uygulama kaydetmek için tıklayın + .
Yeni Tanımlayıcı Kaydet ekranında Uygulama Kimlikleri radyo düğmesini seçin. Ardından Devam'ı seçin.
Yeni uygulamanız için aşağıdaki üç değeri güncelleştirin ve Devam'ı seçin:
Açıklama: Uygulamanız için açıklayıcı bir ad yazın.
Paket Kimliği: com.organization_identifier<> formunun Paket Kimliğini girin.<>UygulamaDağıtım Kılavuzu'nda belirtildiği gibi product_name. Aşağıdaki ekran görüntüsünde
mobcat
, değer kuruluş tanımlayıcısı olarak, PushDemo değeri ise ürün adı olarak kullanılır.Anında İletme Bildirimleri: Özellikler bölümündeki Anında İletme Bildirimleri seçeneğini işaretleyin.
Bu eylem, Uygulama Kimliğinizi oluşturur ve bilgileri onaylamanızı talep eder. Yeni Uygulama Kimliğini onaylamak için Devam'ı ve ardından Kaydet'i seçin.
Kaydet'i seçtikten sonra Yeni Uygulama Kimliği'ni Sertifikalar, Tanımlayıcılar & Profiller sayfasında satır öğesi olarak görürsünüz.
Sertifikalar, Tanımlayıcılar & Profilleri sayfasında, Tanımlayıcılar'ın altında oluşturduğunuz Uygulama Kimliği satır öğesini bulun. Ardından, Uygulama Kimliği Yapılandırmanızı Düzenleyin ekranını görüntülemek için satırını seçin.
Notification Hubs için sertifika oluşturma
Bildirim hub'ının Apple Anında İletme Bildirim Hizmetleri (APNS) ile çalışmasını sağlamak için bir sertifika gereklidir ve iki yoldan biriyle sağlanabilir:
Doğrudan Notification Hub'a yüklenebilecek bir p12 anında iletme sertifikası oluşturma (özgün yaklaşım)
Belirteç tabanlı kimlik doğrulaması için kullanılabilecek bir p8 sertifikası oluşturma (daha yeni ve önerilen yaklaşım)
Daha yeni yaklaşım, APNS için Belirteç tabanlı (HTTP/2) kimlik doğrulamasında belgelendiği gibi bir dizi avantaja sahiptir. Daha az adım gereklidir, ancak belirli senaryolar için de zorunludur. Ancak her iki yaklaşım da bu öğreticinin amaçları doğrultusunda çalışacağından adımlar sağlanmıştır.
SEÇENEK 1: Doğrudan Bildirim Hub'ına yüklenebilecek bir p12 anında iletme sertifikası oluşturma
Mac bilgisayarınızda Anahtarlık Erişimi aracını çalıştırın. Yardımcı Programlar klasöründen veya Başlatma Çubuğundaki Diğer klasöründen açılabilir.
Anahtarlık Erişimi'ni seçin, Sertifika Yardımcısı'nı genişletin ve ardından Sertifika Yetkilisinden Sertifika İste'yi seçin.
Not
Varsayılan olarak, AnahtarLık Erişimi listedeki ilk öğeyi seçer. Sertifikalar kategorisindeyseniz ve Apple Dünya Çapında Geliştirici İlişkileri Sertifika Yetkilisi listedeki ilk öğe değilse bu sorun olabilir. CSR'yi (Sertifika İmzalama İsteği) oluşturmadan önce anahtar olmayan bir öğeye sahip olduğunuzdan veya Apple Worldwide Developer Relations Certification Authority anahtarının seçili olduğundan emin olun.
Kullanıcı Email Adresinizi seçin, Ortak Ad değerinizi girin, Diske kaydedildi'yi belirttiğinizden emin olun ve ardından Devam'ı seçin. Ca Email Adresini boş bırakın çünkü gerekli değildir.
Farklı Kaydet'eSertifika İmzalama İsteği (CSR) dosyası için bir ad girin, Konum'da konumu seçin ve ardından Kaydet'i seçin.
Bu eylem CSR dosyasını seçili konuma kaydeder. Varsayılan konum Masaüstü'dür. Dosya için seçilen konumu unutmayın.
iOS Sağlama Portalı'ndakiSertifikalar, Tanımlayıcılar & Profilleri sayfasına dönün, ekranı aşağı kaydırarak işaretli Anında İletme Bildirimleri seçeneğine gelin ve sertifikayı oluşturmak için Yapılandır'ı seçin.
Apple Anında İletme Bildirimi hizmeti TLS/SSL Sertifikaları penceresi görüntülenir. Geliştirme TLS/SSL Sertifikası bölümünün altında Sertifika Oluştur düğmesini seçin.
Yeni Sertifika Oluştur ekranı görüntülenir.
Not
Bu öğreticide bir geliştirme sertifikası kullanılır. Üretim sertifikası kaydederken de aynı işlem kullanılır. Bildirim gönderirken aynı sertifika türünü kullandığınızdan emin olun.
Dosya Seç'i seçin, CSR dosyasını kaydettiğiniz konuma gidin ve ardından sertifika adına çift tıklayarak dosyayı yükleyin. Ardından Devam'ı seçin.
Portal sertifikayı oluşturdıktan sonra İndir düğmesini seçin. Sertifikayı kaydedin ve kaydedildiği konumu unutmayın.
Sertifika indirilir ve bilgisayarınıza İndirilenler klasörünüze kaydedilir.
Not
Varsayılan olarak, indirilen geliştirme sertifikası aps_development.cer olarak adlandırılır.
İndirilen anında iletme sertifikası aps_development.cer çift tıklayın. Bu eylem, aşağıdaki görüntüde gösterildiği gibi yeni sertifikayı Anahtarlık'a yükler:
Not
Sertifikanızdaki ad farklı olsa da, adın önüne Apple Development iOS Anında İletme Hizmetleri eklenir ve ilgili paket tanımlayıcısı bulunur.
Anahtarlık Erişimi'nde Denetim + Sertifikalar kategorisinde oluşturduğunuz yeni anında iletme sertifikasınatıklayın. Dışarı Aktar'ı seçin, dosyayı adlandırın, p12 biçimini seçin ve ardından Kaydet'i seçin.
Sertifikayı parolayla korumayı seçebilirsiniz, ancak parola isteğe bağlıdır. Parola oluşturmayı atlamak istiyorsanız Tamam'a tıklayın. Dışarı aktarılan p12 sertifikasının dosya adını ve konumunu not edin. Bunlar APN'lerle kimlik doğrulamasını etkinleştirmek için kullanılır.
Not
p12 dosya adınız ve konumunuz bu öğreticide çizilenden farklı olabilir.
SEÇENEK 2: Belirteç tabanlı kimlik doğrulaması için kullanılabilecek bir p8 sertifikası oluşturma
Aşağıdaki ayrıntıları not edin:
- Uygulama Kimliği Ön Eki (Ekip Kimliği)
- Paket Kimliği
Sertifikalar, Tanımlayıcılar & Profiller'e dönün ve Anahtarlar'a tıklayın.
Not
APNS için yapılandırılmış bir anahtarınız varsa, indirdiğiniz p8 sertifikasını oluşturulduktan hemen sonra yeniden kullanabilirsiniz. Bu durumda , 3 ile 5 arasında adımları yoksayabilirsiniz.
+ Yeni bir anahtar oluşturmak için düğmeye (veya Anahtar oluştur düğmesine) tıklayın.
Uygun bir Anahtar Adı değeri sağlayın, ardından Apple Anında İletme Bildirimleri hizmeti (APNS) seçeneğini işaretleyin ve ardından Devam'a ve ardından bir sonraki ekranda Kaydet'e tıklayın.
İndir'e tıklayın ve p8 dosyasını (AuthKey_ ön ekli) güvenli bir yerel dizine taşıyın ve ardından Bitti'ye tıklayın.
Not
p8 dosyanızı güvenli bir yerde tuttuğunuzdan emin olun (ve yedek kaydedin). Anahtarınızı indirdikten sonra, sunucu kopyası kaldırıldıktan sonra yeniden indirilemez.
Anahtarlar'da, oluşturduğunuz anahtara (veya bunun yerine bunu kullanmayı seçtiyseniz mevcut bir anahtara) tıklayın.
Anahtar Kimliği değerini not edin.
p8 sertifikanızı Visual Studio Code gibi tercihinize uygun bir uygulamada açın. Anahtar değerini not edin ( -----BEGIN PRIVATE KEY----- ile -----END PRIVATE KEY----- arasında).
-----BEGIN ÖZEL ANAHTARI-----
<key_value>
-----END ÖZEL ANAHTARı-----Not
Bu, daha sonra Notification Hub'ı yapılandırmak için kullanılacak belirteç değeridir.
Bu adımların sonunda, bildirim hub'ınızı APNS bilgileriyle yapılandırma bölümünde kullanmak üzere aşağıdaki bilgilere sahip olmanız gerekir:
- Ekip Kimliği (bkz. 1. adım)
- Paket Kimliği (bkz. 1. adım)
- Anahtar Kimliği (bkz. 7. adım)
- Belirteç değeri (8. adımda alınan p8 anahtar değeri)
Uygulama için sağlama profili oluşturma
iOS Sağlama Portalı'na dönün, Sertifikalar, Tanımlayıcılar & Profiller'i seçin, sol menüden Profiller'i seçin ve ardından yeni bir profil oluşturmak için seçin+. Yeni Sağlama Profili Kaydet ekranı görüntülenir.
Sağlama profili türü olarak Geliştirme'nin altında iOS Uygulama Geliştirme'yi ve ardından Devam'ı seçin.
Ardından, Uygulama Kimliği açılan listesinden oluşturduğunuz uygulama kimliğini seçin ve Devam'ı seçin.
Sertifikaları seçin penceresinde, kod imzalama için kullandığınız geliştirme sertifikasını seçin ve Devam'ı seçin.
Not
Bu sertifika, önceki adımda oluşturduğunuz anında iletme sertifikası değil. Bu, geliştirme sertifikanızdır. Yoksa, bu öğreticinin önkoşulu olduğundan bunu oluşturmanız gerekir. Geliştirici sertifikaları, Xcode aracılığıyla veya Visual Studio'daApple Geliştirici Portalı'nda oluşturulabilir.
Sertifikalar, Tanımlayıcılar & Profiller sayfasına dönün, sol menüden Profiller'i seçin ve ardından yeni bir profil oluşturmak için öğesini seçin+. Yeni Sağlama Profili Kaydet ekranı görüntülenir.
Sertifika seç penceresinde, oluşturduğunuz geliştirme sertifikasını seçin. Ardından Devam'ı seçin.
Ardından test için kullanılacak cihazları seçin ve Devam'ı seçin.
Son olarak, Sağlama Profili Adı'nda profil için bir ad seçin ve Oluştur'u seçin.
Yeni sağlama profili oluşturulduğunda İndir'i seçin. Kaydedildiği konumu unutmayın.
Sağlama profilinin konumuna göz atın ve ardından geliştirme makinenize yüklemek için çift tıklayın.
Bildirim Hub'ı oluşturma
Bu bölümde bir bildirim hub'ı oluşturacak ve APNS ile kimlik doğrulamayı yapılandıracaksınız. P12 anında iletme sertifikası veya belirteç tabanlı kimlik doğrulaması kullanabilirsiniz. Önceden oluşturduğunuz bir bildirim hub'ını kullanmak istiyorsanız 5. adıma atlayabilirsiniz.
Azure'da oturum açın.
Kaynak oluştur'a tıklayın, Bildirim Hub'ı arayıp seçin, ardından Oluştur'a tıklayın.
Aşağıdaki alanları güncelleştirin ve oluştur'a tıklayın:
TEMEL AYRINTILAR
Abonelik: Açılan listeden hedef Aboneliği seçin
Kaynak Grubu: Yeni bir Kaynak Grubu oluşturma (veya var olan bir kaynak grubunu seçme)AD ALANı AYRıNTıLARı
Bildirim Hub'ı Ad Alanı:Bildirim Hub'ı ad alanı için genel olarak benzersiz bir ad girin
Not
Bu alan için Yeni oluştur seçeneğinin belirlendiğinden emin olun.
BILDIRIM HUB'ı AYRıNTıLARı
Bildirim Hub'ı:Bildirim Hub'ı için bir ad girin
Konum: Açılan listeden uygun bir konum seçin
Fiyatlandırma Katmanı: Varsayılan Ücretsiz seçeneğini koruNot
Ücretsiz katmanda hub sayısı üst sınırına ulaşmadığınız sürece.
Bildirim Hub'ı sağlandıktan sonra bu kaynağa gidin.
Yeni Bildirim Hub'ınıza gidin.
Listeden Erişim İlkeleri'ni seçin ( YÖNET'in altında).
İlke Adı değerlerini ve ilgili Bağlantı Dizesi değerlerini not edin.
ApNS bilgileriyle Bildirim Hub'ınızı yapılandırma
Bildirim Hizmetleri'nin altında Apple'ı seçin, ardından Notification Hubs için Sertifika Oluşturma bölümünde daha önce seçtiğiniz yaklaşıma göre uygun adımları izleyin.
Not
Uygulama Modu için Üretim'i yalnızca uygulamanızı mağazadan satın alan kullanıcılara anında iletme bildirimleri göndermek istiyorsanız kullanın.
SEÇENEK 1: .p12 anında iletme sertifikası kullanma
Sertifika'ya tıklayın.
Dosya simgesini seçin.
Daha önce dışarı aktardığınız .p12 dosyasını ve ardından Aç'ı seçin.
Gerekirse doğru parolayı belirtin.
Korumalı alan modu'nu seçin.
Kaydet'i seçin.
SEÇENEK 2: Belirteç tabanlı kimlik doğrulamayı kullanma
Belirteç'i seçin.
Daha önce edindiğiniz aşağıdaki değerleri girin:
- Anahtar Kimliği
- Paket Kimliği
- Ekip Kimliği
- Belirte -ci
Korumalı Alan'ı seçin.
Kaydet'i seçin.
Bildirim hub'ınızı FCM bilgileriyle yapılandırma
- Soldaki menünün Ayarlar bölümünde Google (GCM/FCM) öğesini seçin.
- Google Firebase Konsolu'ndan not ettiğiniz sunucu anahtarını girin.
- Araç çubuğunda Kaydet'i seçin.
ASP.NET Core Web API arka uç uygulaması oluşturma
Bu bölümde, cihaz kaydını ve Flutter mobil uygulamasına bildirim göndermeyi işlemek için ASP.NET Core Web API arka ucu oluşturacaksınız.
Web projesi oluşturma
Visual Studio'daDosya>Yeni Çözüm'e tıklayın.
.NET Core>Uygulaması>ASP.NET Core>API>İleri'yi seçin.
Yeni ASP.NET Core Web API'nizi yapılandırın iletişim kutusunda Hedef .NET Core 3.1Çerçevesi'ni seçin.
Proje Adı olarak PushDemoApi girin ve Oluştur'u seçin.
Şablonlu uygulamayı test etmek için hata ayıklamayı başlatın (Command + Enter).
Not
Şablonlu uygulama, launchUrl olarak WeatherForecastController kullanacak şekilde yapılandırılmıştır. Bu, Özellikler>launchSettings.json ayarlanır.
Geçersiz geliştirme sertifikası bulundu iletisi istenirse:
Bunu düzeltmek için 'dotnet dev-certs https' aracını çalıştırmayı kabul etmek için Evet'e tıklayın. 'dotnet dev-certs https' aracı daha sonra sertifika için bir parola ve Anahtar zincirinizin parolasını girmenizi ister.
Yeni sertifikayı yükleyip güvenmeniz istendiğinde Evet'e tıklayın ve anahtarlığınızın parolasını girin.
Denetleyiciler klasörünü genişletin ve WeatherForecastController.cs silin.
WeatherForecast.cs silin.
Gizli Dizi Yöneticisi aracını kullanarak yerel yapılandırma değerlerini ayarlayın. Gizli dizileri çözümden ayırma, bunların kaynak denetiminde yer almamasını sağlar. Terminal'i açın, ardından proje dosyasının dizinine gidin ve aşağıdaki komutları çalıştırın:
dotnet user-secrets init dotnet user-secrets set "NotificationHub:Name" <value> dotnet user-secrets set "NotificationHub:ConnectionString" <value>
Yer tutucu değerlerini kendi bildirim hub'ı adınızla ve bağlantı dizesi değerleriyle değiştirin. Bildirim hub'ı oluşturma bölümünde bunları not edindiniz. Aksi takdirde, bunları Azure'da arayabilirsiniz.
NotificationHub:Name:
Genel Bakış'ın üst kısmındaki Temel Bilgiler özetindeki Ad bölümüne bakın.NotificationHub:ConnectionString:
Erişimİlkeleri'nde DefaultFullSharedAccessSignature bölümüne bakınNot
Üretim senaryolarında, bağlantı dizesi güvenli bir şekilde depolamak için Azure KeyVault gibi seçeneklere bakabilirsiniz. Kolaylık olması için gizli diziler Azure App Service uygulama ayarlarına eklenir.
API Anahtarı kullanarak istemcilerin kimliğini doğrulama (İsteğe bağlı)
API anahtarları belirteçler kadar güvenli değildir, ancak bu öğreticinin amaçları için yeterlidir. API anahtarı , ASP.NET Ara Yazılımı aracılığıyla kolayca yapılandırılabilir.
API anahtarını yerel yapılandırma değerlerine ekleyin.
dotnet user-secrets set "Authentication:ApiKey" <value>
Not
Yer tutucu değerini kendi yer tutucunuzla değiştirip not etmelisiniz.
Denetim + PushDemoApi projesine tıklayın, Eklemenüsünden Yeni Klasör'e tıklayın ve ardından Klasör Adı olarak Kimlik Doğrulaması kullanarak ekle'ye tıklayın.
Denetim + Kimlik Doğrulaması klasörüne tıklayın, ardından Eklemenüsünden Yeni Dosya... öğesini seçin.
Genel>Boş Sınıf'ı seçin, Ad için ApiKeyAuthOptions.cs girin ve ardından Aşağıdaki uygulamayı ekleyen Yeni'ye tıklayın.
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; } } }
ApiKeyAuthHandler.cs adlı Kimlik Doğrulama klasörüne başka bir Boş Sınıf ekleyin ve ardından aşağıdaki uygulamayı ekleyin.
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)); } } }
Not
Kimlik Doğrulama İşleyicisi, bir düzenin davranışını uygulayan bir türdür ve bu durumda özel bir API Anahtarı düzenidir.
ApiKeyAuthenticationBuilderExtensions.cs adlı Kimlik Doğrulama klasörüne başka bir Boş Sınıf ekleyin ve ardından aşağıdaki uygulamayı ekleyin.
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); } } }
Not
Bu uzantı yöntemi, ara yazılım yapılandırma kodunu Startup.cs basitleştirerek daha okunabilir ve genellikle daha kolay takip edilebilir hale getirir.
Startup.cs'daConfigureServices yöntemini güncelleştirerek hizmetlere yapılan çağrının altındaki API Anahtarı kimlik doğrulamasını yapılandırın. AddControllers yöntemi.
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); }
Hala Startup.cs içinde Configure yöntemini güncelleştirerek uygulamanın IApplicationBuilder'ındaUseAuthentication ve UseAuthorization uzantısı yöntemlerini çağırın. Bu yöntemlerin UseRouting'den sonra ve uygulamadan önce çağrıldığından emin olun . 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(); }); }
Not
UseAuthentication çağrısı, önceden kaydedilmiş kimlik doğrulama düzenlerini (ConfigureServices'ten) kullanan ara yazılımı kaydeder. Bu, kimlik doğrulaması yapılan kullanıcılara bağımlı olan herhangi bir ara yazılımdan önce çağrılmalıdır.
Bağımlılık ekleme ve hizmetleri yapılandırma
ASP.NET Core, sınıflar ve bağımlılıkları arasında Denetimin TersIni (IoC) elde etmeye yönelik bir teknik olan bağımlılık ekleme (DI) yazılım tasarım desenini destekler.
Arka uç işlemleri için bildirim hub'ının ve Notification Hubs SDK'sının kullanımı bir hizmet içinde kapsüllenmiş durumdadır. Hizmet, uygun bir soyutlama aracılığıyla kaydedilir ve kullanılabilir hale getirilir.
Denetim + Bağımlılıklar klasörüne tıklayın, ardından NuGet Paketlerini Yönet...'i seçin.
Microsoft.Azure.NotificationHubs araması yapın ve işaretli olduğundan emin olun.
Paket Ekle'ye tıklayın ve ardından lisans koşullarını kabul etmek isteyip istemediğiniz sorulduğunda Kabul Et'e tıklayın.
Denetim + PushDemoApi projesine tıklayın, Eklemenüsünden Yeni Klasör'e tıklayın ve ardından Klasör Adı olarak Modelleri Kullanarak Ekle'ye tıklayın.
Denetim + Modeller klasörüne tıklayın, ardından Eklemenüsünden Yeni Dosya... öğesini seçin.
Genel>Boş Sınıf'ı seçin, Ad için PushTemplates.cs girin ve ardından Aşağıdaki uygulamayı ekleyen Yeni'ye tıklayın.
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)\" }"; } } }
Not
Bu sınıf, bu senaryonun gerektirdiği genel ve sessiz bildirimler için belirteçli bildirim yüklerini içerir. Yüklemeler, hizmet aracılığıyla mevcut yüklemeleri güncelleştirmek zorunda kalmadan denemelere izin vermek için Yükleme dışında tanımlanır. Yüklemelerdeki değişiklikleri bu şekilde işlemek, bu öğreticinin kapsamı dışındadır. Üretim için özel şablonları göz önünde bulundurun.
Models klasörüne DeviceInstallation.cs adlı başka bir Boş Sınıf ekleyin ve ardından aşağıdaki uygulamayı ekleyin.
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>(); } }
Models klasörüne NotificationRequest.cs adlı başka bir Boş Sınıf ekleyin ve ardından aşağıdaki uygulamayı ekleyin.
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; } } }
Models klasörüne NotificationHubOptions.cs adlı başka bir Boş Sınıf ekleyin ve ardından aşağıdaki uygulamayı ekleyin.
using System.ComponentModel.DataAnnotations; namespace PushDemoApi.Models { public class NotificationHubOptions { [Required] public string Name { get; set; } [Required] public string ConnectionString { get; set; } } }
PushDemoApi projesine Hizmetler adlı yeni bir klasör ekleyin.
INotificationService.cs adlı Hizmetler klasörüne Boş Bir Arabirim ekleyin ve ardından aşağıdaki uygulamayı ekleyin.
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); } }
NotificationHubsService.cs adlı Hizmetler klasörüne Boş Bir Sınıf ekleyin, ardından INotificationService arabirimini uygulamak için aşağıdaki kodu ekleyin:
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); } } }
Not
SendTemplateNotificationAsync için sağlanan etiket ifadesi 20 etiketle sınırlıdır. Çoğu işleç için 6 ile sınırlıdır, ancak bu durumda ifade yalnızca OR'leri (||) içerir. İstekte 20'den fazla etiket varsa, bunların birden çok isteğe bölünmesi gerekir. Daha fazla ayrıntı için Yönlendirme ve Etiket İfadeleri belgelerine bakın.
Startup.cs'daConfigureServices yöntemini güncelleştirerek NotificationHubsService'iINotificationService'in tek bir uygulaması olarak ekleyin.
using PushDemoApi.Models; using PushDemoApi.Services; public void ConfigureServices(IServiceCollection services) { ... services.AddSingleton<INotificationService, NotificationHubService>(); services.AddOptions<NotificationHubOptions>() .Configure(Configuration.GetSection("NotificationHub").Bind) .ValidateDataAnnotations(); }
Bildirimler API'sini oluşturma
Denetim + Denetleyiciler klasörüne tıklayın, ardından Eklemenüsünden Yeni Dosya... öğesini seçin.
ASP.NET Core>Web API Denetleyicisi Sınıfı'nı seçin, Ad için NotificationsController girin ve Yeni'ye tıklayın.
Not
Visual Studio 2019 ile takip ediyorsanız okuma/yazma eylemleriyle API Denetleyicisi şablonunu seçin.
Aşağıdaki ad alanlarını dosyanın en üstüne ekleyin.
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;
Şablonlu denetleyiciyi ControllerBase'den türetilen ve ApiController özniteliğiyle süslenen şekilde güncelleştirin.
[ApiController] [Route("api/[controller]")] public class NotificationsController : ControllerBase { // Templated methods here }
Not
Denetleyici temel sınıfı görünümler için destek sağlar, ancak bu durumda bu gerekli değildir ve bu nedenle ControllerBase bunun yerine kullanılabilir. Visual Studio 2019 ile takip ediyorsanız bu adımı atlayabilirsiniz.
İSTEMCIleri api anahtarı kullanarak doğrulama bölümünü tamamlamayı seçtiyseniz NotificationsController'ıDa Authorize özniteliğiyle süslemeniz gerekir.
[Authorize]
Oluşturucuyu , INotificationService'in kayıtlı örneğini bağımsız değişken olarak kabul etmek ve salt okunur bir üyeye atamak için güncelleştirin.
readonly INotificationService _notificationService; public NotificationsController(INotificationService notificationService) { _notificationService = notificationService; }
launchSettings.json'da (Özellikler klasörünün içinde), launchUrl değerini
weatherforecast
api/notifications olarak değiştirerek RegistrationsControllerRoute özniteliğinde belirtilen URL ile eşleşmesini sağlayın.Uygulamanın yeni NotificationsController ile çalıştığını doğrulamak için hata ayıklamayı başlatın (Command + Enter) ve 401 Yetkisiz durumunu döndürür.
Not
Visual Studio uygulamayı tarayıcıda otomatik olarak başlatamayabilir. Bu noktadan sonra API'yi test etmek için Postman kullanacaksınız.
Yeni bir Postman sekmesinde isteği GET olarak ayarlayın. applicationUrl> yer tutucusunu<Özellikler>launchSettings.json bulunan https applicationUrl ile değiştirerek aşağıdaki adresi girin.
<applicationUrl>/api/notifications
Not
applicationUrl varsayılan profil için 'https://localhost:5001' olmalıdır. IIS kullanıyorsanız (Windows üzerinde Visual Studio 2019'da varsayılan), bunun yerine iisSettings öğesinde belirtilen applicationUrl'yi kullanmalısınız. Adres yanlışsa 404 yanıtı alırsınız.
İSTEMCIlerin kimliğini doğrulama bölümünü API Anahtarı kullanarak tamamlamayı seçtiyseniz, istek üst bilgilerini apikey değerinizi içerecek şekilde yapılandırdığınızdan emin olun.
Anahtar Değer apikey <your_api_key> Gönder düğmesine tıklayın.
Not
Bazı JSON içeriğiyle 200 Tamam durumu almalısınız.
SSL sertifika doğrulama uyarısı alırsanız, Ayarlar'dan SSL sertifika doğrulama Postman isteği ayarını kapatabilirsiniz.
NotificationsController.cs şablonlu sınıf yöntemlerini aşağıdaki kodla değiştirin.
[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(); }
API uygulamasını oluşturma
Artık arka uç hizmetini barındırmak için Azure App Service'de bir API Uygulaması oluşturacaksınız.
Azure portal oturum açın.
Kaynak oluştur'a tıklayın, API Uygulaması için arama yapın ve seçin, ardından Oluştur'a tıklayın.
Aşağıdaki alanları güncelleştirin ve oluştur'a tıklayın.
Uygulama adı:
API Uygulaması için genel olarak benzersiz bir ad girinAbonelik:
Bildirim hub'ını oluşturduğunuz hedef Aboneliği seçin.Kaynak Grubu:
Bildirim hub'ını oluşturduğunuz Kaynak Grubunu seçin.App Service Planı/Konumu:
Yeni App Service Planı oluşturmaNot
Varsayılan seçenekten SSL desteği içeren bir plana geçin. Aksi takdirde, http isteklerinin engellenmesini önlemek için mobil uygulamayla çalışırken uygun adımları uygulamanız gerekir.
Application Insights:
Önerilen seçeneği koruyun (bu ad kullanılarak yeni bir kaynak oluşturulur) veya mevcut bir kaynağı seçin.API Uygulaması sağlandıktan sonra bu kaynağa gidin.
Genel Bakış'ın üst kısmındaki Temel Bileşenler özetindeki URL özelliğini not edin. Bu URL, bu öğreticinin ilerleyen bölümlerinde kullanılacak arka uç uç noktanızdır .
Not
URL, daha önce belirttiğiniz API uygulama adını biçiminde
https://<app_name>.azurewebsites.net
kullanır.Listeden Yapılandırma'ya tıklayın ( Ayarlar'ın altında).
Aşağıdaki ayarların her biri için Yeni uygulama ayarı'na tıklayarak Ad ve Değer girin, ardından Tamam'a tıklayın.
Adı Değer Authentication:ApiKey
<api_key_value> NotificationHub:Name
<hub_name_value> NotificationHub:ConnectionString
<hub_connection_string_value> Not
Bunlar, daha önce kullanıcı ayarlarında tanımladığınız ayarlarla aynıdır. Bunları kopyalayabilirsiniz. Authentication:ApiKey ayarı yalnızca BIR API Anahtarı kullanarak istemcilerin kimliğini doğrulama bölümünü tamamlamayı seçtiğinizde gereklidir. Üretim senaryoları için Azure KeyVault gibi seçeneklere bakabilirsiniz. Bunlar, bu örnekte kolaylık sağlamak için uygulama ayarları olarak eklenmiştir.
Tüm uygulama ayarları eklendikten sonra Kaydet'e ve ardından Devam'a tıklayın.
Arka uç hizmetini yayımlama
Ardından, uygulamayı tüm cihazlardan erişilebilir hale getirmek için API Uygulamasına dağıtacaksınız.
Not
Aşağıdaki adımlar Mac için Visual Studio özgü adımlardır. Windows'da Visual Studio 2019 ile takip ediyorsanız yayımlama akışı farklı olacaktır. Bkz. Windows'da Azure App Service yayımlama.
Henüz yapmadıysanız yapılandırmanızı Hata Ayıkla olan Sürüm olarak değiştirin.
Denetim + PushDemoApi projesine tıklayın ve yayımla menüsünden Azure'da Yayımla...öğesini seçin.
İstenirse kimlik doğrulama akışını izleyin. ÖNCEKI API Uygulaması bölümünde kullandığınız hesabı kullanın.
Listeden yayımlama hedefiniz olarak daha önce oluşturduğunuz Azure App Service API Uygulamasını seçin ve yayımla'ya tıklayın.
Sihirbazı tamamladıktan sonra uygulamayı Azure'da yayımlar ve ardından uygulamayı açar. Henüz yapmadıysanız URL'yi not edin. Bu URL, bu öğreticinin ilerleyen bölümlerinde kullanılan arka uç uç noktanızdır .
Yayımlanan API'yi doğrulama
Postman'de yeni bir sekme açın, isteği PUT olarak ayarlayın ve aşağıdaki adresi girin. Yer tutucusunu , önceki arka uç hizmetini yayımlama bölümünde not ettiğiniz temel adresle değiştirin.
https://<app_name>.azurewebsites.net/api/notifications/installations
Not
Temel adres biçiminde olmalıdır
https://<app_name>.azurewebsites.net/
İSTEMCIlerin kimliğini doğrulama bölümünü API Anahtarı kullanarak tamamlamayı seçtiyseniz, istek üst bilgilerini apikey değerinizi içerecek şekilde yapılandırdığınızdan emin olun.
Anahtar Değer apikey <your_api_key> Gövde için ham seçeneği belirleyin, ardından biçim seçenekleri listesinden JSON'u seçin ve ardından bazı yer tutucu JSON içeriği ekleyin:
{}
Gönder'e tıklayın.
Not
Hizmetten 422 UnprocessableEntity durumu almalısınız.
1-4 arası adımları yeniden uygulayın, ancak bu kez 400 Hatalı İstek yanıtı aldığınızı doğrulamak için istekler uç noktasını belirtin.
https://<app_name>.azurewebsites.net/api/notifications/requests
Not
Bunun için istemci mobil uygulamasından platforma özgü bilgiler gerekeceğinden, API'yi geçerli istek verileri kullanarak test etmek henüz mümkün değildir.
Platformlar arası Flutter uygulaması oluşturma
Bu bölümde, anında iletme bildirimlerini platformlar arası bir şekilde uygulayan bir Flutter mobil uygulaması oluşturacaksınız.
Oluşturduğunuz arka uç hizmeti aracılığıyla bir bildirim hub'ından kaydolmanızı ve kaydını kaldırmanızı sağlar.
Bir eylem belirtildiğinde ve uygulama ön planda olduğunda bir uyarı görüntülenir. Aksi takdirde bildirimler bildirim merkezinde görünür.
Not
Kayıt (ve kaydı kaldırma) eylemlerini genellikle uygulama yaşam döngüsünde uygun bir noktada (veya ilk çalıştırma deneyiminizin bir parçası olarak) açık kullanıcı kaydı/kaydını kaldırma girişleri olmadan gerçekleştirirsiniz. Ancak bu örnek, bu işlevselliğin daha kolay keşfedilmesine ve test edilmesine olanak sağlamak için açık kullanıcı girişi gerektirir.
Flutter çözümünü oluşturma
yeni bir Visual Studio Code örneği açın.
Komut Paleti'ni (Shift + Command + P) açın.
Flutter: Yeni Proje komutunu seçip Enter tuşuna basın.
Proje Adı için push_demo girin ve bir Proje konumu seçin.
Bunu yapmanız istendiğinde Paketleri Al'ı seçin.
Denetim + Kotlin klasörüne tıklayın (app>src>main altında) ve finder'da göster'i seçin. Ardından alt klasörleri ( kotlin klasörünün altında)
com
sırasıyla ,<your_organization>
vepushdemo
olarak yeniden adlandırın.Not
Visual Studio Code şablonunu kullanırken bu klasörler varsayılan olarak com, <örneğin project_name> olarak ayarlanır. Mobcat'inkuruluş için kullanıldığını varsayarsak klasör yapısı şu şekilde görünmelidir:
- kotlin
- Com
- mobcat
- pushdemo
- mobcat
- Com
- kotlin
Visual Studio Code geri döndüğünüzde, android> appbuild.gradle içindekiapplicationId> değerini olarak
com.<your_organization>.pushdemo
güncelleştirin.Not
your_organization> yer tutucusu< için kendi kuruluş adınızı kullanmanız gerekir. Örneğin, mobcat'i kuruluş olarak kullanmak com.mobcat.pushdemopaket adı değerine neden olur.
sırasıyla src debug, src>mainve>src>profili altındaAndroidManifest.xmldosyalarındaki paket özniteliğini güncelleştirin. Değerlerin önceki adımda kullandığınız applicationId değeriyle eşleştiğinden emin olun.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.<your_organization>.pushdemo>"> ... </manifest>
android:label
src>main altındaki AndroidManifest.xml dosyasındaki özniteliği PushDemo olarak güncelleştirin. Ardından özniteliğiniandroid:allowBackup
doğrudan altınaandroid:label
ekleyin ve değerini false olarak ayarlayın.<application android:name="io.flutter.app.FlutterApplication" android:label="PushDemo" android:allowBackup="false" android:icon="@mipmap/ic_launcher"> ... </application>
Uygulama düzeyi build.gradle dosyasını (android>app>build.gradle) açın, ardından compileSdkVersion'ı ( android bölümünden) API 29 kullanacak şekilde güncelleştirin. Ardından , minSdkVersion ve targetSdkVersion değerlerini ( defaultConfig bölümünden) sırasıyla 26 ve 29 olarak güncelleştirin.
Not
Bu öğreticinin amaçları doğrultusunda yalnızca API düzeyi 26 ve üzerini çalıştıran cihazlar desteklenir, ancak eski sürümleri çalıştıran cihazları destekleyecek şekilde genişletebilirsiniz.
Denetim + ios klasörüne tıklayın ve Xcode ile Aç'ı seçin.
Xcode'daÇalıştırıcı'ya (klasörün değil üstteki xcodeproj) tıklayın. Ardından , Çalıştırıcı hedefini seçin ve Genel sekmesini seçin. Tüm derleme yapılandırması seçili durumdayken Paket Tanımlayıcısı'nı olarak
com.<your_organization>.PushDemo
güncelleştirin.Not
your_organization> yer tutucusu< için kendi kuruluş adınızı kullanmanız gerekir. Örneğin, mobcat'in kuruluş olarak kullanılması com.mobcat.PushDemoPaket Tanımlayıcısı değerine neden olur.
Info.plist'e tıklayın ve Paket adı değerini PushDemo olarak güncelleştirin
Xcode'ı kapatın ve Visual Studio Code dönün.
Visual Studio Code'dapubspec.yaml dosyasını açın, http ve flutter_secure_storageDart paketlerini bağımlılık olarak ekleyin. Ardından, dosyayı kaydedin ve istendiğinde Paketleri Al'a tıklayın.
dependencies: flutter: sdk: flutter http: ^0.12.1 flutter_secure_storage: ^3.3.3
Terminal'de dizini ios klasörüne değiştirin (Flutter projeniz için). Ardından, yeni podları yüklemek için pod yükleme komutunu yürütebilirsiniz ( flutter_secure_storage paketi için gereklidir).
Denetim + Lib klasörüne tıklayın, ardından dosya adı olarak main_page.dart dosyasını kullanarak menüden Yeni Dosya'yı seçin. Ardından aşağıdaki kodu ekleyin.
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>[], ) ) ); } }
main.dart dosyasında şablonlu kodu aşağıdakiyle değiştirin.
import 'package:flutter/material.dart'; import 'package:push_demo/main_page.dart'; final navigatorKey = GlobalKey<NavigatorState>(); void main() => runApp(MaterialApp(home: MainPage(), navigatorKey: navigatorKey));
Terminal'de, cihazınızdaki şablonlu uygulama çalıştırmalarını test etmek için uygulamayı her hedef platformda derleyin ve çalıştırın. Desteklenen cihazların bağlı olduğundan emin olun.
flutter run
Platformlar arası bileşenleri uygulama
Denetim + Lib klasörüne tıklayın, ardından menüden Klasör Adı olarak modelleri kullanan Yeni Klasör'e tıklayın.
Denetim + models klasörüne tıklayın, ardından dosya adı olarak device_installation.dart dosyasını kullanarak menüden Yeni Dosya'yı seçin. Ardından aşağıdaki kodu ekleyin.
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, }; }
Bu örnekte desteklenen eylemlerin numaralandırmasını tanımlayan push_demo_action.dart adlı models klasörüne yeni bir dosya ekleyin.
enum PushDemoAction { actionA, actionB, }
Projeye hizmetler adlı yeni bir klasör ekleyin ve ardından aşağıdaki uygulamayla device_installation_service.dart adlı klasöre yeni bir dosya ekleyin.
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); } }
Not
your_organization> yer tutucusu< için kendi kuruluş adınızı kullanmanız gerekir. Örneğin, mobcat'i kuruluş olarak kullanmak, com.mobcat.pushdemo/deviceinstallationMethodChannel adıyla sonuçlanır.
Bu sınıf, gerekli cihaz yükleme ayrıntılarını almak için temel alınan yerel platformla çalışmayı kapsüller. MethodChannel, temel alınan yerel platformlarla çift yönlü zaman uyumsuz iletişimi kolaylaştırır. Bu kanalın platforma özgü karşılığı sonraki adımlarda oluşturulacaktır.
Aşağıdaki uygulamayla bu klasöre notification_action_service.dart adlı başka bir dosya ekleyin.
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; } } }
Not
Bu, bildirim eylemlerinin işlenmesini merkezi hale getirmek için basit bir mekanizma olarak kullanılır, böylece bunlar kesin olarak belirlenmiş bir sabit listesi kullanılarak platformlar arası bir şekilde işlenebilir. Hizmet, bildirim yükünde bir eylem belirtildiğinde temel alınan yerel platformun bir eylemi tetiklesine olanak tanır. Ayrıca, Flutter işlemeye hazır olduğunda ortak kodun uygulama başlatma sırasında bir eylemin belirtilip belirtilmediğinde geriye dönük olarak denetlenip denetlenmediğini denetlemesini sağlar. Örneğin, bildirim merkezinden bir bildirime dokunarak uygulama başlatıldığında.
Aşağıdaki uygulamayla notification_registration_service.dart adlı hizmetler klasörüne yeni bir dosya ekleyin.
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; } } }
Not
Bu sınıf , DeviceInstallationService'in kullanımını ve gerekli kayıt, kayıt kaydını kaldırma ve yenileme kayıt eylemlerini gerçekleştirmek için arka uç hizmetine yönelik istekleri kapsüller. apiKey bağımsız değişkeni, yalnızca BIR API Anahtarı kullanarak istemcilerin kimliğini doğrulama bölümünü tamamlamayı seçtiyseniz gereklidir.
Aşağıdaki uygulamayla config.dart adlı lib klasörüne yeni bir dosya ekleyin.
class Config { static String apiKey = "API_KEY"; static String backendServiceEndpoint = "BACKEND_SERVICE_ENDPOINT"; }
Not
Bu, uygulama gizli dizilerini tanımlamanın basit bir yolu olarak kullanılır. Yer tutucu değerlerini kendi değerlerinizle değiştirin. Arka uç hizmetini oluştururken bunları not almış olmanız gerekir. API Uygulaması URL'si olmalıdır
https://<api_app_name>.azurewebsites.net/
. apiKey üyesi, yalnızca bir API Anahtarı kullanarak istemcilerin kimliğini doğrulama bölümünü tamamlamayı seçtiyseniz gereklidir.Bu gizli dizilerin kaynak denetimine işlenmesini önlemek için bunu gitignore dosyanıza eklediğinizden emin olun.
Platformlar arası kullanıcı arabirimini uygulama
main_page.dart'tabuild işlevini aşağıdakiyle değiştirin.
@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, ), ], ), ), ); }
Gerekli içeri aktarmaları main_page.dart dosyasının en üstüne ekleyin.
import 'package:push_demo/services/notification_registration_service.dart'; import 'config.dart';
NotificationRegistrationService başvurusu depolamak için _MainPageState sınıfına bir alan ekleyin.
final notificationRegistrationService = NotificationRegistrationService(Config.backendServiceEndpoint, Config.apiKey);
_MainPageState sınıfında, Sıkıştırılan olaylardaki Kaydet ve Kaydı Kaldır düğmeleri için olay işleyicilerini uygulayın. İlgili Kayıt/Kaldırma yöntemlerini çağırın ve ardından sonucu göstermek için bir uyarı gösterin.
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(); }, ), ], ); }, ); }
Şimdi main.dart dosyasında, dosyanın en üstünde aşağıdaki içeri aktarmaların bulunduğundan emin olun.
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';
NotificationActionService örneğine başvuru depolamak ve başlatmak için bir değişken bildirin.
final notificationActionService = NotificationActionService();
Bir eylem tetiklendiğinde uyarının görüntülenmesini işlemek için işlevler ekleyin.
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(); }, ), ], ); }, ); }
NotificationActionServiceactionTriggered akışını gözlemlemek ve uygulama başlatma sırasında yakalanan eylemleri denetlemek için ana işlevi güncelleştirin.
void main() async { runApp(MaterialApp(home: MainPage(), navigatorKey: navigatorKey,)); notificationActionService.actionTriggered.listen((event) { notificationActionTriggered(event as PushDemoAction); }); await notificationActionService.checkLaunchAction(); }
Not
Bu yalnızca anında iletme bildirimi eylemlerinin makbuzunu ve yayılmasını göstermek için yapılır. Bunlar genellikle, bu durumda uyarı görüntülemek yerine belirli bir görünüme gitmek veya bazı verileri yenilemek gibi sessizce işlenir.
Yerel Android projesini anında iletme bildirimleri için yapılandırma
Google Services JSON dosyasını ekleme
Denetim + Android klasörüne tıklayın, ardından Android Studio'da aç'ı seçin. Ardından Proje görünümüne geçin (henüz değilse).
Daha önce Firebase Konsolu'ndaPushDemo projesini ayarlarken indirdiğiniz google-services.json dosyasını bulun. Ardından uygulama modülü kök dizinine (android android>>uygulaması) sürükleyin.
Derleme ayarlarını ve izinlerini yapılandırma
Proje görünümünü Android olarak değiştirin.
AndroidManifest.xmlaçın, ardından interneti ve READ_PHONE_STATE izinlerini uygulama öğesinden sonra kapanış etiketinden önce ekleyin.
<manifest> <application>...</application> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> </manifest>
Firebase SDK'larını ekleme
Android Studio'da proje düzeyinde build.gradle dosyasını (Gradle Scripts>build.gradle (Project: android)) açın. ve bağımlılıklar düğümünde 'com.google.gms:google-services' sınıf yolu
buildscript
> olduğundan emin olun.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 // ... } }
Not
Android Projesini oluştururken Firebase Konsolu'nda sağlanan yönergelere göre en son sürüme başvurduğunuzdan emin olun.
Uygulama düzeyi build.gradle dosyasında (Gradle Betikleri>build.gradle (Modül: uygulama)) Google Services Gradle eklentisini uygulayın. Eklentiyi android düğümünü hemen üstüne uygulayın.
// ... // Add the following line: apply plugin: 'com.google.gms.google-services' // Google Services plugin android { // ... }
Aynı dosyadaki bağımlılıklar düğümünde Cloud Messaging Android kitaplığının bağımlılığını ekleyin.
dependencies { // ... implementation 'com.google.firebase:firebase-messaging:20.2.0' }
Not
Cloud Messaging Android istemcisi belgelerine göre en son sürüme başvurdığınızdan emin olun.
Değişiklikleri kaydedin, ardından Şimdi Eşitle düğmesine (araç çubuğu isteminden) veya Projeyi Gradle Dosyalarıyla Eşitle'ye tıklayın.
Android için anında iletme bildirimlerini işleme
Android Studio'daDenetim + com.your_organization.pushdemo<> paket klasörüne (app>src>main>kotlin)tıklayın, Yeni menüsünden Paket'i seçin. Ad olarak hizmetler yazın ve Return tuşuna basın.
Denetim + Hizmetler klasörüne tıklayın, Yenimenüsünden Kotlin Dosyası/Sınıfı'nı seçin. Ad olarak DeviceInstallationService yazın ve Return tuşuna basın.
Aşağıdaki kodu kullanarak DeviceInstallationService'i uygulayın.
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" } }
Not
Bu sınıf kanal için
com.<your_organization>.pushdemo/deviceinstallation
platforma özgü karşılığı uygular. Bu, DeviceInstallationService.dart içindeki uygulamanın Flutter bölümünde tanımlanmıştır. Bu durumda, çağrılar ortak koddan yerel konağa yapılır. your_organization nerede kullanılırsa kullanılsın kendi kuruluşunuzla değiştirildiğinden <emin olun.>Bu sınıf, bildirim hub'ı kayıt yükünün bir parçası olarak benzersiz bir kimlik ( Secure.AndroidId kullanarak) sağlar.
NotificationRegistrationService adlı hizmetler klasörüne başka bir Kotlin Dosyası/Sınıfı ekleyin ve ardından aşağıdaki kodu ekleyin.
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) } }
Not
Bu sınıf kanal için
com.<your_organization>.pushdemo/notificationregistration
platforma özgü karşılığı uygular. Bu, NotificationRegistrationService.dart içindeki uygulamanın Flutter bölümünde tanımlanmıştır. Bu durumda, çağrılar yerel ana bilgisayardan ortak koda yapılır. Bu özelliğin kullanıldığı her yerde your_organization> kendi kuruluşunuzla değiştirmeyi< de dikkat edin.NotificationActionService adlı hizmetler klasörüne başka bir Kotlin Dosyası/Sınıfı ekleyin ve ardından aşağıdaki kodu ekleyin.
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() } } } }
Not
Bu sınıf kanal için
com.<your_organization>.pushdemo/notificationaction
platforma özgü karşılığı uygular. Bu, NotificationActionService.dart içindeki uygulamanın Flutter bölümünde tanımlanmıştır. Bu durumda çağrılar her iki yönde de yapılabilir. your_organization nerede kullanılırsa kullanılsın kendi kuruluşunuzla değiştirildiğinden <emin olun.>com.your_organization.pushdemo<> paketine PushNotificationsFirebaseMessagingService adlı yeni bir Kotlin Dosyası/Sınıfı ekleyin ve aşağıdaki kodu kullanarak uygulayın.
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)) } } } }
Not
Bu sınıf, uygulama ön planda çalışırken bildirimleri işlemekle sorumludur. onMessageReceived içinde alınan bildirim yüküne bir eylem dahil edilirse NotificationActionService üzerindeki triggerAction öğesini koşullu olarak çağırır. Bu, Firebase belirteci onNewToken işlevini geçersiz kılarak yeniden oluşturulduğunda NotificationRegistrationService üzerinde refreshRegistration'ı da çağırır.
Bir kez daha, your_organization> kullanıldığı her yerde kendi kuruluşunuzla değiştirmeyi< deneyin.
AndroidManifest.xml (app>src>main) içinde, amaç filtresiyle
com.google.firebase.MESSAGING_EVENT
uygulama öğesinin en altına PushNotificationsFirebaseMessagingService öğesini ekleyin.<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>
DeviceInstallationService'e döndüğünüzde, dosyanın en üstünde aşağıdaki içeri aktarmaların bulunduğundan emin olun.
package com.<your_organization>.pushdemo import com.<your_organization>.pushdemo.services.PushNotificationsFirebaseMessagingService
Not
your_organization kendi kuruluş değerinizle değiştirin<.>
PushNotificationFirebaseMessagingService'ten belirteç değerini almak için yer tutucu metin Placeholder_Get_Value_From_FirebaseMessagingService_Implementation güncelleştirin.
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 }
MainActivity'de dosyanın en üstünde aşağıdaki içeri aktarmaların bulunduğundan emin olun.
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
Not
your_organization kendi kuruluş değerinizle değiştirin<.>
DeviceInstallationService başvurusu depolamak için bir değişken ekleyin.
private lateinit var deviceInstallationService: DeviceInstallationService
Amacınaction adlı fazladan bir değeri olup olmadığını denetlemek için processNotificationActions adlı bir işlev ekleyin. Bu eylemi koşullu olarak tetikleyin veya eylem uygulama başlatma sırasında işleniyorsa daha sonra kullanmak üzere depolayın.
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) } } } }
processNotificationActions çağrısı yapmak için onNewIntent işlevini geçersiz kılın.
override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) processNotificationActions(intent) }
Not
MainActivity için LaunchModeSingleTop olarak ayarlandığından, var olan Etkinlik örneğine onCreate işlevi yerine onNewIntent işlevi aracılığıyla bir Intent gönderilir ve bu nedenle hem onCreate hem de onNewIntent işlevlerinde gelen bir Amacı işlemeniz gerekir.
onCreate işlevini geçersiz kılın, deviceInstallationService değerini deviceInstallationService'in yeni bir örneği olarak ayarlayın.
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) flutterEngine?.let { deviceInstallationService = DeviceInstallationService(context, it) } }
PushNotificationFirebaseMessagingServices üzerinde notificationActionService ve notificationRegistrationService özelliklerini ayarlayın.
flutterEngine?.let { deviceInstallationService = DeviceInstallationService(context, it) PushNotificationsFirebaseMessagingService.notificationActionService = NotificationActionService(it) PushNotificationsFirebaseMessagingService.notificationRegistrationService = NotificationRegistrationService(it) }
Aynı işlevde, FirebaseInstanceId.getInstance().instanceId öğesini koşullu olarak çağırın. refreshRegistration çağrılmadan önce PushNotificationFirebaseMessagingService'te sonuçta elde edilen belirteç değerini ayarlamak için OnCompleteListener'ı uygulayın.
if(deviceInstallationService?.playServicesAvailable) { FirebaseInstanceId.getInstance().instanceId .addOnCompleteListener(OnCompleteListener { task -> if (!task.isSuccessful) return@OnCompleteListener PushNotificationsFirebaseMessagingService.token = task.result?.token PushNotificationsFirebaseMessagingService.notificationRegistrationService?.refreshRegistration() }) }
Hala onCreate içinde, işlevin sonunda processNotificationActions öğesini çağırın. Bu eylemin uygulama başlatma sırasında işlendiğini belirtmek için launchAction bağımsız değişkeni için true kullanın.
processNotificationActions(this.intent, true)
Not
Anında iletme bildirimleri almaya devam etmek için uygulamayı her çalıştırdığınızda yeniden kaydetmeniz ve hata ayıklama oturumundan durdurmanız gerekir.
Yerel iOS projesini anında iletme bildirimleri için yapılandırma
Runner hedefini ve Info.plist'i yapılandırma
Visual Studio Code'da, Denetim + ios klasörünetıklayın ve Xcode ile Aç'ı seçin.
Xcode'daÇalıştırıcı'ya (klasörün değil üstteki xcodeproj) tıklayın, ardından Çalıştırıcı hedefini seçin ve ardından İmzalama & Yetenekleri. Tüm derleme yapılandırması seçiliyken Ekip için Geliştirici hesabınızı seçin. "İmzayı otomatik olarak yönet" seçeneğinin işaretli olduğundan ve İmzalama Sertifikanızın ve Sağlama Profilinizin otomatik olarak seçildiğinden emin olun.
Not
Yeni Sağlama Profili değerini görmüyorsanız Xcode>Tercihleri>Hesabı'nı ve ardından profilleri indirmek için El ile Profilleri İndir düğmesini seçerek İmzalama Kimliği profillerini yenilemeyi deneyin.
+ Yetenek'e tıklayın ve anında iletme bildirimleri için arama yapın. Bu özelliği eklemek için Anında İletme Bildirimleri'neçift tıklayın.
Info.plist dosyasını açın ve En düşük sistem sürümünü13.0 olarak ayarlayın.
Not
Yalnızca iOS 13.0 ve üzerini çalıştıran cihazlar bu öğreticinin amaçları doğrultusunda desteklenir, ancak eski sürümleri çalıştıran cihazları destekleyecek şekilde genişletebilirsiniz.
Runner.entitlements dosyasını açın ve APS Ortamı ayarının geliştirme olarak ayarlandığından emin olun.
iOS için anında iletme bildirimlerini işleme
Denetim + Çalıştırıcı klasörüne tıklayın (Çalıştırıcı projesinin içinde), ardından ad olarak Hizmetleri kullanan Yeni Grup'u seçin.
Denetim + Hizmetler klasörüne tıklayın ve ardından Yeni Dosya... öğesini seçin. Ardından Swift Dosyası'nı seçin ve İleri'ye tıklayın. Ad için DeviceInstallationService değerini belirtin ve Oluştur'a tıklayın.
Aşağıdaki kodu kullanarak DeviceInstallationService.swift uygulayın.
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." } }
Not
Bu sınıf kanal için
com.<your_organization>.pushdemo/deviceinstallation
platforma özgü karşılığı uygular. Bu, DeviceInstallationService.dart içindeki uygulamanın Flutter bölümünde tanımlanmıştır. Bu durumda, çağrılar ortak koddan yerel konağa yapılır. your_organization nerede kullanılırsa kullanılsın kendi kuruluşunuzla değiştirildiğinden <emin olun.>Bu sınıf, bildirim hub'ı kayıt yükünün bir parçası olarak benzersiz bir kimlik ( UIDevice.identifierForVendor değerini kullanarak) sağlar.
NotificationRegistrationService adlı Hizmetler klasörüne başka bir Swift Dosyası ekleyin ve ardından aşağıdaki kodu ekleyin.
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) } }
Not
Bu sınıf kanal için
com.<your_organization>.pushdemo/notificationregistration
platforma özgü karşılığı uygular. Bu, NotificationRegistrationService.dart içindeki uygulamanın Flutter bölümünde tanımlanmıştır. Bu durumda, çağrılar yerel ana bilgisayardan ortak koda yapılır. Bu özelliğin kullanıldığı her yerde your_organization> kendi kuruluşunuzla değiştirmeyi< de dikkat edin.NotificationActionService adlı Hizmetler klasörüne başka bir Swift Dosyası ekleyin ve ardından aşağıdaki kodu ekleyin.
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) } } }
Not
Bu sınıf kanal için
com.<your_organization>.pushdemo/notificationaction
platforma özgü karşılığı uygular. Bu, NotificationActionService.dart içindeki uygulamanın Flutter bölümünde tanımlanmıştır. Bu durumda çağrılar her iki yönde de yapılabilir. your_organization nerede kullanılırsa kullanılsın kendi kuruluşunuzla değiştirildiğinden <emin olun.>AppDelegate.swift'te, daha önce oluşturduğunuz hizmetlere yönelik bir başvuruyu depolamak için değişkenler ekleyin.
var deviceInstallationService : DeviceInstallationService? var notificationRegistrationService : NotificationRegistrationService? var notificationActionService : NotificationActionService?
Bildirim verilerini işlemek için processNotificationActions adlı bir işlev ekleyin. Bu eylemi koşullu olarak tetikleyin veya eylem uygulama başlatma sırasında işleniyorsa daha sonra kullanmak üzere depolayın.
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) } } }
DeviceInstallationServiceiçin belirteç değerini ayarlayıp didRegisterForRemoteNotificationsWithDeviceToken işlevini geçersiz kılın. Ardından NotificationRegistrationService üzerinde refreshRegistration çağrısı yapın.
override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { deviceInstallationService?.token = deviceToken notificationRegistrationService?.refreshRegistration() }
userInfo bağımsız değişkenini processNotificationActions işlevine geçirerek didReceiveRemoteNotification işlevini geçersiz kılın.
override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) { processNotificationActions(userInfo: userInfo) }
Hatayı günlüğe kaydetmek için didFailToRegisterForRemoteNotificationsWithError işlevini geçersiz kılın.
override func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print(error); }
Not
Bu çok yer tutucudur. Üretim senaryoları için düzgün günlüğe kaydetme ve hata işleme uygulamak isteyeceksiniz.
didFinishLaunchingWithOptions içinde deviceInstallationService, notificationRegistrationService ve notificationActionService değişkenlerini başlatın.
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController deviceInstallationService = DeviceInstallationService(withBinaryMessenger: controller.binaryMessenger) notificationRegistrationService = NotificationRegistrationService(withBinaryMessenger: controller.binaryMessenger) notificationActionService = NotificationActionService(withBinaryMessenger: controller.binaryMessenger)
Aynı işlevde koşullu olarak yetkilendirme isteyin ve uzak bildirimlere kaydolun.
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() } } } }
launchOptions, remoteNotification anahtarını içeriyorsa didFinishLaunchingWithOptions işlevinin sonunda processNotificationActions öğesini çağırın. Sonuçta elde edilen userInfo nesnesini geçirin ve launchAction bağımsız değişkeni için true değerini kullanın. Gerçek bir değer, eylemin uygulama başlatma sırasında işlendiğini belirtir.
if let userInfo = launchOptions?[.remoteNotification] as? [AnyHashable : Any] { processNotificationActions(userInfo: userInfo, launchAction: true) }
Çözümü test edin
Artık arka uç hizmeti aracılığıyla bildirim göndermeyi test edebilirsiniz.
Test bildirimi gönderme
Postman'de yeni bir sekme açın.
İsteği POST olarak ayarlayın ve aşağıdaki adresi girin:
https://<app_name>.azurewebsites.net/api/notifications/requests
İstemcileri API Anahtarı kullanarak doğrula bölümünü tamamlamayı seçtiyseniz, istek üst bilgilerini apikey değerinizi içerecek şekilde yapılandırdığınızdan emin olun.
Anahtar Değer apikey <your_api_key> Gövde için ham seçeneği belirleyin, ardından biçim seçenekleri listesinden JSON'u seçin ve ardından bazı yer tutucu JSON içeriği ekleyin:
{ "text": "Message from Postman!", "action": "action_a" }
Pencerenin sağ üst kısmındaki Kaydet düğmesinin altındaki Kod düğmesini seçin. İstek, HTML için görüntülendiğinde aşağıdaki örneğe benzer görünmelidir ( apikey üst bilgisi ekleyip eklemediğinize bağlı olarak):
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" }
PushDemo uygulamasını hedef platformlardan birinde veya her ikisinde (Android ve iOS) çalıştırın.
Not
Android'de test ediyorsanız Hata Ayıklama'da çalışmadığınızdan emin olun veya uygulama çalıştırılarak dağıtıldıysa, uygulamayı kapatmaya zorlayın ve başlatıcıdan yeniden başlatın.
PushDemo uygulamasında Kaydet düğmesine dokunun.
Postman'e geri dönün, Kod Parçacıkları Oluştur penceresini kapatın (henüz yapmadıysanız) ardından Gönder düğmesine tıklayın.
Postman'de200 Tamam yanıtı aldığınızı ve uygulamada ActionA eyleminin alındığını gösteren uyarının görüntülendiğini doğrulayın.
PushDemo uygulamasını kapatın, ardından Postman'daGönder düğmesine yeniden tıklayın.
Postman'deyeniden 200 Ok yanıtı aldığınızdan doğrulayın. PushDemo uygulamasının bildirim alanında doğru iletiyle bir bildirimin göründüğünü doğrulayın.
Uygulamayı açtığını ve EylemA eylemi alındı uyarısını görüntülediğini onaylamak için bildirime dokunun.
Postman'e geri döndüğünüzde, eylemdeğeri içinaction_a yerine action_b belirten sessiz bir bildirim göndermek için önceki istek gövdesini değiştirin.
{ "action": "action_b", "silent": true }
Uygulama hala açıkken Postman'deGönder düğmesine tıklayın.
Postman'de200 Tamam yanıtı aldığınızı ve uyarının uygulamada ActionA eylemi alındı yerine Alınan EylemB eylemini gösteren görüntülendiğini doğrulayın.
PushDemo uygulamasını kapatın, ardından Postman'daGönder düğmesine yeniden tıklayın.
Postman'de200 Ok yanıtı aldığınızdan ve sessiz bildirimin bildirim alanında görünmediğini doğrulayın.
Sorun giderme
Arka uç hizmetinden yanıt yok
Yerel olarak test ederken arka uç hizmetinin çalıştığından ve doğru bağlantı noktasını kullandığından emin olun.
Azure API Uygulaması'na karşı test ediyorsanız hizmetin çalıştığını ve dağıtıldığını ve hatasız olarak başlatıldığını denetleyin.
İstemci aracılığıyla test ederken Postman'da veya mobil uygulama yapılandırmasında temel adresi doğru belirttiğinizden emin olun. Temel adres, yerel olarak https://<api_name>.azurewebsites.net/
test ederken veya https://localhost:5001/
şeklinde olmalıdır.
Hata ayıklama oturumunu başlattıktan veya durdurduktan sonra Android'de bildirim alınmıyor
Hata ayıklama oturumunu başlattıktan veya durdurduktan sonra yeniden kaydolduğunuzdan emin olun. Hata ayıklayıcısı yeni bir Firebase belirtecinin oluşturulmasına neden olur. Bildirim hub'ı yüklemesinin de güncelleştirilmiş olması gerekir.
Arka uç hizmetinden 401 durum kodu alma
apikey istek üst bilgisini ayarladığınızı ve bu değerin arka uç hizmeti için yapılandırdığınız değerle eşleşip eşleşmediğini doğrulayın.
Yerel olarak test ederken bu hatayı alırsanız, istemci yapılandırmasında tanımladığınız anahtar değerinin API tarafından kullanılan Authentication:ApiKey kullanıcı ayarı değeriyle eşleştiğinden emin olun.
Bir API Uygulaması ile test ediyorsanız, istemci yapılandırma dosyasındaki anahtar değerinin API Uygulamasında kullandığınız Authentication:ApiKey uygulama ayarıyla eşleştiğinden emin olun.
Not
Arka uç hizmetini dağıttıktan sonra bu ayarı oluşturduysanız veya değiştirdiyseniz, etkili olması için hizmeti yeniden başlatmanız gerekir.
İSTEMCIleri API Anahtarı kullanarak doğrulama bölümünü tamamlamamayı seçtiyseniz, NotificationsController sınıfına Authorize özniteliğini uygulamadığınızdan emin olun.
Arka uç hizmetinden 404 durum kodu alma
Uç noktanın ve HTTP istek yönteminin doğru olduğunu doğrulayın. Örneğin uç noktaların şu şekilde olması gerekir:
- [PUT]
https://<api_name>.azurewebsites.net/api/notifications/installations
- [DELETE]
https://<api_name>.azurewebsites.net/api/notifications/installations/<installation_id>
- [POSTA]
https://<api_name>.azurewebsites.net/api/notifications/requests
Veya yerel olarak test ederken:
- [PUT]
https://localhost:5001/api/notifications/installations
- [DELETE]
https://localhost:5001/api/notifications/installations/<installation_id>
- [POSTA]
https://localhost:5001/api/notifications/requests
İstemci uygulamasında temel adresi belirtirken ile sona erdiğinden /
emin olun. Temel adres, yerel olarak https://<api_name>.azurewebsites.net/
test ederken veya https://localhost:5001/
şeklinde olmalıdır.
Kaydedilemiyor ve bildirim hub'ı hata iletisi görüntüleniyor
Test cihazının ağ bağlantısı olduğunu doğrulayın. Ardından, HttpResponse içindeki StatusCode özellik değerini incelemek için bir kesme noktası ayarlayarak Http yanıt durum kodunu belirleyin.
Durum koduna göre uygun olduğunda önceki sorun giderme önerilerini gözden geçirin.
İlgili API için bu özel durum kodlarını döndüren satırlarda bir kesme noktası ayarlayın. Ardından yerel olarak hata ayıklarken arka uç hizmetini çağırmayı deneyin.
Uygun yükü kullanarak Postman aracılığıyla arka uç hizmetinin beklendiği gibi çalıştığını doğrulayın. Söz konusu platform için istemci kodu tarafından oluşturulan gerçek yükü kullanın.
Hiçbir adımın kaçırılmadığından emin olmak için platforma özgü yapılandırma bölümlerini gözden geçirin. Uygun platform için ve token
değişkenleri için installation id
uygun değerlerin çözümlenip çözümlenmediğini denetleyin.
Cihaz kimliği çözümlenemiyor hata iletisi görüntüleniyor
Hiçbir adımın kaçırılmadığından emin olmak için platforma özgü yapılandırma bölümlerini gözden geçirin.
İlgili bağlantılar
- Azure Notification Hubs'a genel bakış
- macOS'ta Flutter yükleme
- Windows'a Flutter yükleme
- Arka uç işlemleri için Notification Hubs SDK'sı
- GitHub'da Notification Hubs SDK'sı
- Uygulama arka ucuna kaydolma
- Kayıt yönetimi
- Etiketlerle çalışma
- Özel şablonlarla çalışma
Sonraki adımlar
Artık bir arka uç hizmeti aracılığıyla bir bildirim hub'ına bağlı temel bir Flutter uygulamasına sahip olmanız ve bildirim gönderip alabilmeniz gerekir.
Büyük olasılıkla bu öğreticide kullanılan örneği kendi senaryonuza uyacak şekilde uyarlamanız gerekir. Daha güçlü hata işleme, yeniden deneme mantığı ve günlüğe kaydetme de önerilir.
Visual Studio App Center , sorun gidermeye yardımcı olmak için analiz ve tanılama sağlayan mobil uygulamalara hızlıca eklenebilir.