Firebase ile Push Notification İşlemleri

Merhabalar,

En popüler push notification servisleri ile Xamarin entegrasyonunu gerçekleştirmiştik ama direkt Firebase kullanımını hep atladık. Bunun en büyük sebebi aracı servislerin çok kolay entegre edilmesi ve zengin özellikli olmasıydı. Fakat geldiğimiz noktada en popüler pn servislerinden biri olan AppCenter, push notification servisini kapattı, OneSignal entegrasyonu ise gereksiz efor ve bence OneSignal iOS entegrasyonu işkence seviyesinde.

Olayın hikaye kısmını geçip hızlı bir şekilde firebase console ayarlarımızı yapıp, kodlarımızı yazalım.

Vitamini Çekirdeğinde

https://console.firebase.google.com adresine gidip yeni bir proje oluşturalım.

Kullanacağımız plugin : Firebase Push Notification Plugin for Xamarin iOS and Android

Android

AndroidManifest içerisinde application tagleri arasına,

    <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
    <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
      <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
        <category android:name="com.firebase.xamocan" />
      </intent-filter>
    </receiver>

Firebase console üzerindeki Cloud messaging sekmesinden Android uygulamamızı ekleyelim

Paket ve uygulama adını girdikten sonra google-services.json dosyasını Android projenizin içine ekleyerek gerekli ayarların buradan okunacağını gösterebilirsiniz fakat ben genelde bunu direkt kullandığımız yardımcı plugin aracılığıyla yapıyorum.

MainApplication.cs

[Application]
    public class MainApplication : Application, Application.IActivityLifecycleCallbacks
    {
        public MainApplication(IntPtr handle, JniHandleOwnership transer) : base(handle, transer)
        {

        }

        public override void OnCreate()
        {
            base.OnCreate();

            RegisterActivityLifecycleCallbacks(this);

            var options = new FirebaseOptions.Builder()
                  .SetApplicationId("1:631842******************")
                  .SetApiKey("AIza*********************")
                  .SetDatabaseUrl("https://xamo*******firebaseio.com")
                  .SetStorageBucket("xamo********appspot.com")
                  .SetGcmSenderId("6318**********").Build();
            var fapp = FirebaseApp.InitializeApp(this, options);

            if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
            {
                FirebasePushNotificationManager.DefaultNotificationChannelId = "DefaultChannel";
                FirebasePushNotificationManager.DefaultNotificationChannelName = "General";
            }


#if DEBUG
            FirebasePushNotificationManager.Initialize(this, new NotificationUserCategory[]
            {
            new NotificationUserCategory("message",new List<NotificationUserAction> {
                new NotificationUserAction("Reply","Reply",NotificationActionType.Foreground),
                new NotificationUserAction("Forward","Forward",NotificationActionType.Foreground)

            }),
            new NotificationUserCategory("request",new List<NotificationUserAction> {
                new NotificationUserAction("Accept","Accept",NotificationActionType.Default,"check"),
                new NotificationUserAction("Reject","Reject",NotificationActionType.Default,"cancel")
            })

            }, true);
#else
	            FirebasePushNotificationManager.Initialize(this,new NotificationUserCategory[]
		    {
			new NotificationUserCategory("message",new List<NotificationUserAction> {
			    new NotificationUserAction("Reply","Reply",NotificationActionType.Foreground),
			    new NotificationUserAction("Forward","Forward",NotificationActionType.Foreground)

			}),
			new NotificationUserCategory("request",new List<NotificationUserAction> {
			    new NotificationUserAction("Accept","Accept",NotificationActionType.Default,"check"),
			    new NotificationUserAction("Reject","Reject",NotificationActionType.Default,"cancel")
			})

		    }, false);
#endif

            //CrossFirebasePushNotification.Current.OnNotificationReceived += (s, p) =>
            //{
            //    System.Diagnostics.Debug.WriteLine("NOTIFICATION RECEIVED", p.Data);
            //};
        }

        public override void OnTerminate()
        {
            base.OnTerminate();
            UnregisterActivityLifecycleCallbacks(this);
        }

        public void OnActivityCreated(Activity activity, Bundle savedInstanceState)
        {
            CrossCurrentActivity.Current.Activity = activity;
        }

        public void OnActivityDestroyed(Activity activity)
        {
        }

        public void OnActivityPaused(Activity activity)
        {
        }

        public void OnActivityResumed(Activity activity)
        {
            CrossCurrentActivity.Current.Activity = activity;
        }

        public void OnActivitySaveInstanceState(Activity activity, Bundle outState)
        {
        }

        public void OnActivityStarted(Activity activity)
        {
            CrossCurrentActivity.Current.Activity = activity;
        }

        public void OnActivityStopped(Activity activity)
        {
        }
    }

CurrentActivity plugin’i de yüklemeyi unutmayalım : Plugin.CurrentActivity

FirebaseOptions.Builder() için gerekli bilgileri indirdiğiniz .json dosyasında bulabilirsiniz.

MainActivity.cs

protected override void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);

            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
            FirebasePushNotificationManager.NotificationActivityType = typeof(MainActivity);
            FirebasePushNotificationManager.NotificationActivityFlags = ActivityFlags.SingleTop;
            FirebasePushNotificationManager.DefaultNotificationChannelImportance = NotificationImportance.Min;
            FirebasePushNotificationManager.ProcessIntent(this, Intent);
        }


FirebaseRegistrar.cs

public class FirebaseRegistrar
    {
        public static void FirebaseInit()
        {
            CrossFirebasePushNotification.Current.OnTokenRefresh += (s, p) =>
            {
                System.Diagnostics.Debug.WriteLine($"TOKEN REC: {p.Token}");
                CrossFirebasePushNotification.Current.Subscribe("general");
            };

            CrossFirebasePushNotification.Current.OnNotificationReceived += (s, p) =>
            {
            };

            CrossFirebasePushNotification.Current.OnNotificationOpened += (s, p) =>
            {
            };


            CrossFirebasePushNotification.Current.OnNotificationAction += (s, p) =>
            {
                System.Diagnostics.Debug.WriteLine("Action");
                if (!string.IsNullOrEmpty(p.Identifier))
                {
                    System.Diagnostics.Debug.WriteLine($"ActionId: {p.Identifier}");
                    foreach (var data in p.Data)
                    {
                        System.Diagnostics.Debug.WriteLine($"{data.Key} : {data.Value}");
                    }
                }
            };

            CrossFirebasePushNotification.Current.OnNotificationDeleted += (s, p) =>
            {
                System.Diagnostics.Debug.WriteLine("Dismissed");
            };
        }
    }
  • Tek bir kullanıcıya bildirim göndermek istiyorsanız OnTokenRefresh eventinin size verdiği token özelliğini kullanmanız gerekiyor.
  • Belirli bir tag içerisindeki kullanıcılara bildirim göndermek istiyorsanız CrossFirebasePushNotification.Current.Subscribe(“general”); methoduna kullanarak kullanıcıları tagleyebilirsiniz. Örnek olması açısından doğum yerine göre tagleme yapabilirsiniz.
    CrossFirebasePushNotification.Current.Subscribe(“Mersin”);
    CrossFirebasePushNotification.Current.Subscribe(“Adana”);

İlk testi yapalım

FirebaseRegistrar sınıfı sayesinde zaten tüm yardımcı eventlere sahibiz. Yardımcı sınıfımız zaten shared katmanda olduğu için iOS ve Android özelinde bir geliştirme yapmamıza da gerek yok.

iOS

AppDelegate.cs

LoadApplication(new App()); methodunun hemen altına;

FirebasePushNotificationManager.Initialize(options, new NotificationUserCategory[]
            {
                    new NotificationUserCategory("message",new List<NotificationUserAction> {
                        new NotificationUserAction("Reply","Reply",NotificationActionType.Foreground)
                    }),
                    new NotificationUserCategory("request",new List<NotificationUserAction> {
                        new NotificationUserAction("Accept","Accept"),
                        new NotificationUserAction("Reject","Reject",NotificationActionType.Destructive)
                    })

            });

            FirebasePushNotificationManager.CurrentNotificationPresentationOption = 
                UNNotificationPresentationOptions.Alert | UNNotificationPresentationOptions.Badge | UNNotificationPresentationOptions.Sound;

İndirdiğimiz GoogleService-Info.plist dosyasını bu sefer iOS projemizin içine atıp Build Action kısmını BundleResource olarak seçelim.

info.plist içerisinden background işlemlerinden remote notifications seçeneğini açmalıyız.

Firebase console üzerinde yapmamız gereken çok ufak bir işlem kaldı o da .p12 dosyasını oluşturup yüklemek.

.p12 dosyası oluşturmayı bilmeyenler linkteki videonun ilk 25 dakikasını izlesinler.

Postman üzerinden denemek isterseniz
https://fcm.googleapis.com/fcm/send adresini kullanabilirsiniz. Header kısmın’a Authorization eklemeyi unutmayın.

{
  "to": "/topics/Adana",
  "notification": {
    "title": "Adana İle İlgili Sözler",
    "body": "Nerelisin dedikleri zaman Adanalıyık deriz",
    "sound": "default",
    "content_available" : true
  }
}

Takıldığınız yerler olursa yorum olarak sorabilirsiniz.

Yiğit

Xamarin Developer, Consultant & Architect. Community Leader and Director of Xamarin Türkiye

2 Comments

You can post comments in this post.


  • Hocam merhaba , xamarin ile push notification göndermek istiyorum ama Firebase Admin SDK dışında XMPP protocolü ile cihazdan cihaza upstream message göndermek istiyorum.Xamarinde yeniyim ve yaklaşık 2 haftadır araştırma yapıyorum . Android studio da smack library kullanarak ve php server ile yapan bi arkadaş gördüm ama ben xamarin ve web service kullanarak yapmak istiyorum . Xamarinde yeni olduğum için mimariyi kafamda oturtamadım yardımcı olabilme şansınız var mı ?

    Ali Akçekoce 3 ay ago Reply


    • Bu islem icin direkt SignalR kullanman daha guzel olabilir 🙂

      Yiğit 3 ay ago Reply


Post A Reply