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.
Google-Service.json download this JSON file.
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.
if (Xamarin.Forms.Application.Current.Properties.ContainsKey("DeviceToken")) { string token = App.Current.Properties["DeviceToken"] as string; //store this token in server database. }
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; }
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 }
That's amazing informative post, I want to add one more thing, If you want to make your web visitor to your subscriber then you should definitely check gravitec lifetime deal Best push notification for website ever.
ReplyDeleteUserful information. I have tried to get the token using the above blog. Trigger is not happening in Firebaseservice.cs. Can you please guide how to resolve or any changes is in need to do
ReplyDelete