Aracılığıyla paylaş


Öğretici: Arka uç hizmeti aracılığıyla Azure Notification Hubs kullanarak Flutter uygulamalarına anında iletme bildirimleri gönderme

Örneği İndir Örneği indirme

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:

Önkoşullar

Birlikte ilerlemek için şunlar gerekir:

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:

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.

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

  1. 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.

  2. Projenizi oluşturduktan sonra Android uygulamanıza Firebase Ekle'yi seçin.

    Android uygulamanıza Firebase ekleme

  3. Android uygulamanıza Firebase ekle sayfasında aşağıdaki adımları uygulayın.

    1. Android paketi adı için paketiniz için bir ad girin. Örneğin: com.<organization_identifier>.<package_name>.

      Paket adını belirtin

    2. Uygulamayı kaydet'i seçin.

    3. google-services.json İndir'i seçin. Ardından dosyayı daha sonra kullanmak üzere yerel bir klasöre kaydedin ve İleri'yi seçin.

      İndirme google-services.json

    4. İleri'yi seçin.

    5. 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.

  4. Firebase konsolunda projenizin dişlisini seçin. Ardından Proje Ayarları'nı seçin.

    Proje Ayarları'nı seçin

    Not

    google-services.json dosyasını indirmediyseniz bu sayfadan indirebilirsiniz.

  5. Ü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.

    Sunucu anahtarını kopyalama

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.

  1. 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 + .

    iOS Sağlama Portalı Uygulama Kimlikleri sayfası

  2. Yeni Tanımlayıcı Kaydet ekranında Uygulama Kimlikleri radyo düğmesini seçin. Ardından Devam'ı seçin.

    iOS Sağlama Portalı yeni kimlik kaydetme sayfası

  3. 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.

      iOS Sağlama Portalı kayıt uygulaması kimliği sayfası

    • Anında İletme Bildirimleri: Özellikler bölümündeki Anında İletme Bildirimleri seçeneğini işaretleyin.

      Yeni uygulama kimliğini kaydetme formu

      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.

      Yeni Uygulama Kimliğini Onayla

      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.

  4. 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:

  1. Doğrudan Notification Hub'a yüklenebilecek bir p12 anında iletme sertifikası oluşturma (özgün yaklaşım)

  2. 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
  1. 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.

  2. Anahtarlık Erişimi'ni seçin, Sertifika Yardımcısı'nı genişletin ve ardından Sertifika Yetkilisinden Sertifika İste'yi seçin.

    Yeni sertifika istemek için Anahtarlık Erişimi'ni kullanma

    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.

  3. 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.

    Beklenen sertifika bilgileri

  4. 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.

    Sertifika için bir dosya adı 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.

  5. 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.

    Uygulama Kimliğini Düzenle sayfası

  6. 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.

    Uygulama Kimliği için sertifika oluştur düğmesi

    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.

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

  8. Portal sertifikayı oluşturdıktan sonra İndir düğmesini seçin. Sertifikayı kaydedin ve kaydedildiği konumu unutmayın.

    Oluşturulan sertifika indirme sayfası

    Sertifika indirilir ve bilgisayarınıza İndirilenler klasörünüze kaydedilir.

    İndirilenler klasöründe sertifika dosyasını bulma

    Not

    Varsayılan olarak, indirilen geliştirme sertifikası aps_development.cer olarak adlandırılır.

  9. İ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:

    Yeni sertifikayı gösteren anahtarlık erişim sertifikaları listesi

    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.

  10. 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ı p12 biçimi olarak dışarı aktarma

    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
  1. Aşağıdaki ayrıntıları not edin:

    • Uygulama Kimliği Ön Eki (Ekip Kimliği)
    • Paket Kimliği
  2. 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.

  3. + Yeni bir anahtar oluşturmak için düğmeye (veya Anahtar oluştur düğmesine) tıklayın.

  4. 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.

  5. İ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.

  6. Anahtarlar'da, oluşturduğunuz anahtara (veya bunun yerine bunu kullanmayı seçtiyseniz mevcut bir anahtara) tıklayın.

  7. Anahtar Kimliği değerini not edin.

  8. 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

  1. 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.

  2. Sağlama profili türü olarak Geliştirme'nin altında iOS Uygulama Geliştirme'yi ve ardından Devam'ı seçin.

    Sağlama profili listesi

  3. Ardından, Uygulama Kimliği açılan listesinden oluşturduğunuz uygulama kimliğini seçin ve Devam'ı seçin.

    Uygulama Kimliği'ni seçin

  4. 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.

  5. 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.

  6. Sertifika seç penceresinde, oluşturduğunuz geliştirme sertifikasını seçin. Ardından Devam'ı seçin.

  7. Ardından test için kullanılacak cihazları seçin ve Devam'ı seçin.

  8. Son olarak, Sağlama Profili Adı'nda profil için bir ad seçin ve Oluştur'u seçin.

    Sağlama profili adı seçme

  9. Yeni sağlama profili oluşturulduğunda İndir'i seçin. Kaydedildiği konumu unutmayın.

  10. 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.

  1. Azure'da oturum açın.

  2. Kaynak oluştur'a tıklayın, Bildirim Hub'ı arayıp seçin, ardından Oluştur'a tıklayın.

  3. 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 koru

    Not

    Ücretsiz katmanda hub sayısı üst sınırına ulaşmadığınız sürece.

  4. Bildirim Hub'ı sağlandıktan sonra bu kaynağa gidin.

  5. Yeni Bildirim Hub'ınıza gidin.

  6. Listeden Erişim İlkeleri'ni seçin ( YÖNET'in altında).

  7. İ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

  1. Sertifika'ya tıklayın.

  2. Dosya simgesini seçin.

  3. Daha önce dışarı aktardığınız .p12 dosyasını ve ardından Aç'ı seçin.

  4. Gerekirse doğru parolayı belirtin.

  5. Korumalı alan modu'nu seçin.

  6. Kaydet'i seçin.

SEÇENEK 2: Belirteç tabanlı kimlik doğrulamayı kullanma

  1. Belirteç'i seçin.

  2. Daha önce edindiğiniz aşağıdaki değerleri girin:

    • Anahtar Kimliği
    • Paket Kimliği
    • Ekip Kimliği
    • Belirte -ci
  3. Korumalı Alan'ı seçin.

  4. Kaydet'i seçin.

Bildirim hub'ınızı FCM bilgileriyle yapılandırma

  1. Soldaki menünün Ayarlar bölümünde Google (GCM/FCM) öğesini seçin.
  2. Google Firebase Konsolu'ndan not ettiğiniz sunucu anahtarını girin.
  3. 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

  1. Visual Studio'daDosya>Yeni Çözüm'e tıklayın.

  2. .NET Core>Uygulaması>ASP.NET Core>API>İleri'yi seçin.

  3. Yeni ASP.NET Core Web API'nizi yapılandırın iletişim kutusunda Hedef .NET Core 3.1Çerçevesi'ni seçin.

  4. Proje Adı olarak PushDemoApi girin ve Oluştur'u seçin.

  5. Ş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:

    1. 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.

    2. Yeni sertifikayı yükleyip güvenmeniz istendiğinde Evet'e tıklayın ve anahtarlığınızın parolasını girin.

  6. Denetleyiciler klasörünü genişletin ve WeatherForecastController.cs silin.

  7. WeatherForecast.cs silin.

  8. 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ın

    Not

    Ü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.

  1. 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.

  2. 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.

  3. Denetim + Kimlik Doğrulaması klasörüne tıklayın, ardından Eklemenüsünden Yeni Dosya... öğesini seçin.

  4. 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; }
        }
    }
    
  5. 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.

  6. 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.

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

  1. Denetim + Bağımlılıklar klasörüne tıklayın, ardından NuGet Paketlerini Yönet...'i seçin.

  2. Microsoft.Azure.NotificationHubs araması yapın ve işaretli olduğundan emin olun.

  3. 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.

  4. 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.

  5. Denetim + Modeller klasörüne tıklayın, ardından Eklemenüsünden Yeni Dosya... öğesini seçin.

  6. 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.

  7. 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>();
        }
    }
    
  8. 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; }
        }
    }
    
  9. 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; }
        }
    }
    
  10. PushDemoApi projesine Hizmetler adlı yeni bir klasör ekleyin.

  11. 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);
        }
    }
    
  12. 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.

  13. 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

  1. Denetim + Denetleyiciler klasörüne tıklayın, ardından Eklemenüsünden Yeni Dosya... öğesini seçin.

  2. 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.

  3. 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;
    
  4. Ş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.

  5. İSTEMCIleri api anahtarı kullanarak doğrulama bölümünü tamamlamayı seçtiyseniz NotificationsController'ıDa Authorize özniteliğiyle süslemeniz gerekir.

    [Authorize]
    
  6. 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;
    }
    
  7. launchSettings.json'da (Özellikler klasörünün içinde), launchUrl değerini weatherforecastapi/notifications olarak değiştirerek RegistrationsControllerRoute özniteliğinde belirtilen URL ile eşleşmesini sağlayın.

  8. 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.

  9. 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.

  10. İ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>
  11. 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.

  12. 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.

  1. Azure portal oturum açın.

  2. 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.

  3. 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 girin

    Abonelik:
    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şturma

    Not

    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.

  4. API Uygulaması sağlandıktan sonra bu kaynağa gidin.

  5. 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.netkullanır.

  6. Listeden Yapılandırma'ya tıklayın ( Ayarlar'ın altında).

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

  8. 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.

  1. Henüz yapmadıysanız yapılandırmanızı Hata Ayıkla olan Sürüm olarak değiştirin.

  2. Denetim + PushDemoApi projesine tıklayın ve yayımla menüsünden Azure'da Yayımla...öğesini seçin.

  3. İstenirse kimlik doğrulama akışını izleyin. ÖNCEKI API Uygulaması bölümünde kullandığınız hesabı kullanın.

  4. 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

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

  2. İ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>
  3. 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:

    {}
    
  4. Gönder'e tıklayın.

    Not

    Hizmetten 422 UnprocessableEntity durumu almalısınız.

  5. 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

  1. yeni bir Visual Studio Code örneği açın.

  2. Komut Paleti'ni (Shift + Command + P) açın.

  3. Flutter: Yeni Proje komutunu seçip Enter tuşuna basın.

  4. Proje Adı için push_demo girin ve bir Proje konumu seçin.

  5. Bunu yapmanız istendiğinde Paketleri Al'ı seçin.

  6. 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) comsırasıyla , <your_organization>ve pushdemo 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
  7. Visual Studio Code geri döndüğünüzde, android> appbuild.gradle içindekiapplicationId> değerini olarak com.<your_organization>.pushdemogü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.

  8. 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>
    
  9. android:labelsrc>main altındaki AndroidManifest.xml dosyasındaki özniteliği PushDemo olarak güncelleştirin. Ardından özniteliğini android:allowBackup doğrudan altına android:labelekleyin 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>
    
  10. 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.

  11. Denetim + ios klasörüne tıklayın ve Xcode ile Aç'ı seçin.

  12. 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>.PushDemogü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.

  13. Info.plist'e tıklayın ve Paket adı değerini PushDemo olarak güncelleştirin

  14. Xcode'ı kapatın ve Visual Studio Code dönün.

  15. 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
    
  16. 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).

  17. 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>[],
            )
          )
        );
      }
    }
    
  18. 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));
    
  19. 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

  1. 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.

  2. 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,
        };
    }
    
  3. 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,
    }
    
  4. 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.

  5. 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.

  6. 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.

  7. 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ırhttps://<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

  1. 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,
              ),
            ],
          ),
        ),
      );
    }
    
  2. 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';
    
  3. NotificationRegistrationService başvurusu depolamak için _MainPageState sınıfına bir alan ekleyin.

    final notificationRegistrationService = NotificationRegistrationService(Config.backendServiceEndpoint, Config.apiKey);
    
  4. _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();
                  },
                ),
              ],
            );
          },
        );
      }
    
  5. Ş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';
    
  6. NotificationActionService örneğine başvuru depolamak ve başlatmak için bir değişken bildirin.

    final notificationActionService = NotificationActionService();
    
  7. 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();
                },
              ),
            ],
          );
        },
      );
    }
    
  8. 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

  1. 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).

  2. 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

  1. Proje görünümünü Android olarak değiştirin.

  2. 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

  1. 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.

  2. 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 {
      // ...
    }
    
  3. 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.

  4. 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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.>

  6. 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.

  7. AndroidManifest.xml (app>src>main) içinde, amaç filtresiyle com.google.firebase.MESSAGING_EVENTuygulama öğ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>
    
  8. 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<.>

  9. 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
    }
    
  10. 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<.>

  11. DeviceInstallationService başvurusu depolamak için bir değişken ekleyin.

    private lateinit var deviceInstallationService: DeviceInstallationService
    
  12. 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)
                }
            }
        }
    }
    
  13. 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.

  14. 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)
        }
    }
    
  15. PushNotificationFirebaseMessagingServices üzerinde notificationActionService ve notificationRegistrationService özelliklerini ayarlayın.

    flutterEngine?.let {
      deviceInstallationService = DeviceInstallationService(context, it)
      PushNotificationsFirebaseMessagingService.notificationActionService = NotificationActionService(it)
      PushNotificationsFirebaseMessagingService.notificationRegistrationService = NotificationRegistrationService(it)
    }
    
  16. 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()
            })
    }
    
  17. 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

  1. Visual Studio Code'da, Denetim + ios klasörünetıklayın ve Xcode ile Aç'ı seçin.

  2. 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.

  3. + 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.

  4. 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.

  5. 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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.>

  6. 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?
    
  7. 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)
            }
        }
    }
    
  8. 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()
    }
    
  9. 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)
    }
    
  10. 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.

  11. 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)
    
  12. 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()
              }
          }
      }
    }
    
  13. 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

  1. Postman'de yeni bir sekme açın.

  2. İsteği POST olarak ayarlayın ve aşağıdaki adresi girin:

    https://<app_name>.azurewebsites.net/api/notifications/requests
    
  3. İ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>
  4. 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"
    }
    
  5. 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"
    }
    
  6. 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.

  7. PushDemo uygulamasında Kaydet düğmesine dokunun.

  8. 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.

  9. 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.

  10. PushDemo uygulamasını kapatın, ardından Postman'daGönder düğmesine yeniden tıklayın.

  11. 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.

  12. Uygulamayı açtığını ve EylemA eylemi alındı uyarısını görüntülediğini onaylamak için bildirime dokunun.

  13. 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
    }
    
  14. Uygulama hala açıkken Postman'deGönder düğmesine tıklayın.

  15. 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.

  16. PushDemo uygulamasını kapatın, ardından Postman'daGönder düğmesine yeniden tıklayın.

  17. 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.

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.