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.
21 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 4 sene ago
Bu islem icin direkt SignalR kullanman daha guzel olabilir 🙂
Yiğit 4 sene ago
cihaza özel token i nasıl okuyacağız?
hangi dosyalar hangi katmanda olacak, yardımcı olabilir misiniz?
HuseyinCelik 4 sene ago
FirebaseRegistrar classi icerisindeki CrossFirebasePushNotification.Current.OnTokenRefresh event’i sana yardimci olacaktir 🙂
Yiğit 4 sene ago
Merhabalar,
acaba yapılan örnek projeyi paylaşabilmeniz mümkün mü?
Muhammet Deregözü 4 sene ago
Selam,
Ilgili yaziyi adim-adim takip ederseniz sorunsuz bir sekilde entegrasyonu yapabilirsiniz. Maalesef kodlari paylasmamisim github uzerinde.
Yiğit 4 sene ago
Android için bütün adımları izliyorum fakat bildirim yolladığım zaman FirebaseRegistrar’a düşmüyor. Gördüğüm tek fark google.json’da DatabaseUrl yok. Json entegrasyon kısmını farklı bir şekilde entegre edebilir miyiz?
Kagan 4 sene ago
MainApplication.cs kısmındaki gibi de ekleyebilirsiniz.
Yiğit 4 sene ago
Push atarken örnek veriyorum 20.000 kişi veya üzeri kişiye push atmaya çalıştığımda limit’e takılıyorum. Firebase’de böyle bir limit kısıtlaması var mıdır ? Varsa eğer, çözümü varsa nedir ?
Ahmet Selçuk 4 sene ago
Merhaba,https://firebase.google.com/docs/firestore/quotas kısmından inceleyebilirsin.
Yiğit 4 sene ago
web.api veya service ile nasıl bildirim gönderebiliriz.
SAİM HASANUSTA 4 sene ago
https://fcm.googleapis.com/fcm/send bu endpointi kullanmanız gerekmekte.
Yiğit 4 sene ago
Hocam merhaba,
Birden fazla projeye (farklı packagename sahip) eş zamanlı olarak bildirim gönderebilmek mümkün mü? Packagename değiştiğiştirdiğimiz de hata almaktayız.
Hamza Duman 3 sene ago
Projenizin packagename’i firebase icerisinde actiginiz projeniz ile eslestiriliyor. Bu yuzden hata vermesi normal 🙂
Yiğit 3 sene ago
Merhabalar,
Tüm adımları gerçekleştirdim. Fakat loglarda başarılı görünmesine rağmen CrossFirebasePushNotification.Current.OnTokenRefresh metoduna düşmedi. Nereye bakmam gerek?
[FirebaseApp] Device unlocked: initializing all Firebase APIs for app [DEFAULT]
[FirebaseInitProvider] FirebaseApp initialization successful
Zafer Uygur 3 sene ago
Hocam Mobil tarafta gelen Key Value Datalarımızı yakalıyoruz. Peki diğer taraftan hidden birşey Id gibi göndermek istersek ne yapmalıyız
Ahmet Talha Şahin 3 sene ago
Hocam Notification’ı pushlarken title ve body gönderdiğimiz gibi hidden bir değer nasıl gönderebilirim
Ahmet Talha Şahin 3 sene ago
Proje nereden başlıyor. Eklenen sınıfları tetikleme işlemi nasıl yapılıyor. Onları da buraya ekleseydiniz iyi olurdu. Projenin içerisine dediğiniz sınıfları ekledik. Bildirim gönderiyoruz. Hiç bir yere etkileşimde olduğu yok. Projenin dosyalarının olduğu resmi ekleseydiniz en sona hiç olmazsa oradan anlaşılırdı
MURAT GÜLER 3 sene ago
Yapılan işlemler ve tüm kodlar post içerisinde paylaşıldı. Eksik olan bir durum yok. Post paylaşılalı neredeyse iki yıl olacak 🙂 Paketlerde veya Firebase ayarlarında farklılıklar oluşmuş olabilir.
Yiğit 3 sene ago
FirebaseInit methoduna nereden başvuru yapılıyor? Çok fazla eksi bilgi var…
Mehmet 2 sene ago
Zaten yazdığınnız kodlar çok kısa bu yazdıklarınızı github’a atsanız bundan sonra faydalanacak olanlar içinde çok iyi olur.
MURAT GÜLER 3 sene ago
Post A Reply