Push Notification Configuration For Android
Plugin Required (Android)
Install Following Plugin in your Xamarin Android Project.
Xamarin.GooglePlayServices.Base
Xamarin.Google.Dagger
Now Create Notification Channel in MainActivity.cs & Configure Notificationin FirebaseService.cs Class in Android Project.
Xamarin.Android Project
MainActivity.cs
using System;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.OS;
using FFImageLoading.Forms.Platform;
namespace TestApp.Droid
{
[Activity(Label = "TestApp", Icon = "@drawable/AppIcon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
static readonly string TAG = "MainActivity";
internal static readonly string CHANNEL_ID = "AndroidChanel";
internal static readonly int NOTIFICATION_ID = 100;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
CreateNotificationChannel();
LoadApplication(new App());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
void CreateNotificationChannel()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
var channel = new NotificationChannel(CHANNEL_ID,
"FCM Notifications",
NotificationImportance.Default)
{
Description = "Firebase Cloud Messages appear in this channel"
};
var notificationManager = (NotificationManager)GetSystemService(Android.Content.Context.NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
}
}
Services/FirebaseService.cs
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using AndroidX.Core.App;
using Firebase.Messaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestApp.Droid.Services
{
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class FirebaseService : FirebaseMessagingService
{
public FirebaseService()
{
}
public async override void OnNewToken(string p0)
{
base.OnNewToken(p0);
if (Xamarin.Forms.Application.Current.Properties.ContainsKey("DeviceToken"))
{
Xamarin.Forms.Application.Current.Properties.Remove("DeviceToken");
}
Xamarin.Forms.Application.Current.Properties.Add("DeviceToken", p0);
await Xamarin.Forms.Application.Current.SavePropertiesAsync();
}
public override void OnMessageReceived(RemoteMessage message)
{
base.OnMessageReceived(message);
var notification = message.GetNotification();
SendNotification(notification.Body, notification.Title, message.Data);
}
void SendNotification(string messageBody, string title, IDictionary<string, string> data)
{
try
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
foreach (var key in data.Keys)
{
intent.PutExtra(key, data[key]);
}
var pendingIntent = PendingIntent.GetActivity(this,
MainActivity.NOTIFICATION_ID,
intent,
PendingIntentFlags.OneShot);
var notificationBuilder = new NotificationCompat.Builder(this, MainActivity.CHANNEL_ID)
.SetSmallIcon(Resource.Drawable.AppIcon)
.SetContentTitle(title)
.SetContentText(messageBody)
.SetAutoCancel(true)
.SetBadgeIconType(Resource.Drawable.AppIcon)
.SetContentIntent(pendingIntent);
var notificationManager = NotificationManagerCompat.From(this);
notificationManager.Notify(MainActivity.NOTIFICATION_ID, notificationBuilder.Build());
}
catch (Exception ex)
{
string mmsg = ex.Message;
}
}
}
}
Google Firebase Console.
Create New Project in Google Firebase Console.
Then Select Project Overview Option.
Click on +Add App Option & Select Android Project.
Add your Android Project Package Name here and then click on Register App.
You will get the package name from the AndroidManifest.xml file.
Google-Service.json download this JSON file.
Now Add this JSON file to your Android Project.
Now Right-click on the google-service.json file and Select Properties Option.
Select BuildAction : GoogleServiceJson
Copy to Output Directory: Do not copy.
Note: If you are not able to see GoogleServiceJson Build Action, Then Install the Following Plugin in your Android Project.
Xamarin.GooglePlayServices.Base
Xamarin.Google.Dagger
Push Notification Configuration For Android
Plugin Required (iOS)
Install Following Plugin in your Xamarin iOS Project.
Xamarin.Firebase.iOS.CloudMessaging
AppDelegate.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Firebase.CloudMessaging;
using Foundation;
using UIKit;
using UserNotifications;
namespace TestApp.iOS
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate, IUNUserNotificationCenterDelegate, IMessagingDelegate
{
//
// This method is invoked when the application has loaded and is ready to run. In this
// method you should instantiate the window, load the UI into it and then make the window
// visible.
//
// You have 17 seconds to return from this method, or iOS will terminate your application.
//
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
// iOS 10 or later
var authOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound;
UNUserNotificationCenter.Current.RequestAuthorization(authOptions, (granted, error) =>
{
Console.WriteLine(granted);
});
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.Current.Delegate = this;
// For iOS 10 data message (sent via FCM)
Messaging.SharedInstance.AutoInitEnabled = true;
Messaging.SharedInstance.Delegate = this;
}
else
{
// iOS 9 or before
var allNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
var settings = UIUserNotificationSettings.GetSettingsForTypes(allNotificationTypes, null);
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
}
UIApplication.SharedApplication.RegisterForRemoteNotifications();
Firebase.InstanceID.InstanceId.Notifications.ObserveTokenRefresh((sender, e) =>
{
Firebase.InstanceID.InstanceId.SharedInstance.GetInstanceId(async (result, error) =>
{
if (error == null)
{
string token = result.Token;
if (Xamarin.Forms.Application.Current.Properties.ContainsKey("DeviceToken"))
{
Xamarin.Forms.Application.Current.Properties.Remove("DeviceToken");
}
Xamarin.Forms.Application.Current.Properties.Add("DeviceToken", token);
await Xamarin.Forms.Application.Current.SavePropertiesAsync();
//do something with token
}
else
{
Console.WriteLine("couldn't get Firebase Token: " + error);
}
});
});
return base.FinishedLaunching(app, options);
}
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
SendLocalNotification(userInfo);
}
void SendLocalNotification(NSDictionary message)
{
try
{
var apsDictionary = message["aps"] as NSDictionary;
var alertDictionary = apsDictionary["alert"] as NSDictionary;
if (alertDictionary.Count > 0)
{
string title = alertDictionary["title"].ToString();
string body = alertDictionary["body"].ToString();
var notification = new UILocalNotification
{
FireDate = NSDate.FromTimeIntervalSinceNow(5),
AlertAction = title,
AlertBody = body,
SoundName = UILocalNotification.DefaultSoundName
};
UIApplication.SharedApplication.ScheduleLocalNotification(notification);
}
}
catch (Exception ex)
{
}
}
}
}
Create New Project in Google Firebase Console.
Then Select Project Overview Option.
Click on +Add App Option & Select iOS Project.
Add your iOS Project Bundle Identifier here and then click on Register App.
You will get the Bundle Identifier from the Info.plist file.
Download GoogleService-Info.plist file and add this file to your Xamarin iOS Project.
Now Add this GoogleService-Info.plist file to your ios Project.
Select BuildAction: BundleResource
Copy to Output Directory: Do not copy.
APN Configuration
Now Open the Google FirebaseConsole => Project Setting => Cloud Messaging.
TeamID: You will get it from the Apple Developer Account Membership Details Page.
KeyID: Is the ID of APN Key added in Keys option of Certificates & Identifiers & Profiles Page.
APN Key you will get from Apple Developer Account
Implementation In Xamarin Form Project.
Storing Device Token to Server Database.
if (Xamarin.Forms.Application.Current.Properties.ContainsKey("DeviceToken"))
{
string token = App.Current.Properties["DeviceToken"] as string;
//store this token in server database.
}
Sending Push Notification to Device Token
await SendPushNotification(new PushNotificationRequest
{
registration_ids = deviceTokens,
notification = new { title = "title", body = "message", data = new NotificationBody { body = "Message", title = "Title"} }
});
public async Task<bool> SendPushNotification(PushNotificationRequest request)
{
bool isNotificationSent = false;
try
{
string url = "https://fcm.googleapis.com/fcm/send";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("key", "=" + "Cloud Messaging Server Key");
string jsonObject = JsonConvert.SerializeObject(request);
var response = await client.PostAsync(url, new StringContent(jsonObject, Encoding.UTF8, "application/json"));
var content = await response.Content.ReadAsStringAsync();
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
isNotificationSent = true;
}
}
}
catch (Exception ex)
{
string msg = ex.Message;
}
return isNotificationSent;
}
Cloud Messaging Server Key: You will get from FirebaseConsole => Project Setting => Cloud Messaging.
PushNotificationRequest Class
public class PushNotificationRequest
{
public List<string> registration_ids { get; set; } = new List<string>(); // List of Device Token
public object notification { get; set; }
public NotificationBody data { get; set; } // Notification body
}