azure notification issue: apns works while template not response - xamarin.forms

Follow this tutorial "Add push notifications to your Xamarin.Forms app" for Xamarin.Forms development. After insert notification code in Azure backend and iOS, the notification template send out but no alert on device. However, the test sending of APNS shows the alert on the device. Appreciate any suggestion.
Here is my RegisteredForRemoteNotifications
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
const string templateBodyAPNS = "{\"aps\":{\"alert\":\"$(message)\"}}";
JObject templates = new JObject();
templates["genericMessage"] = new JObject
{
{"body", templateBodyAPNS}
};
/*
// Register for push with your mobile app
Push push = TodoItemManager.DefaultManager.CurrentClient.GetPush();
try
{
push.RegisterAsync(deviceToken, templates);
}
catch (System.Exception ex)
{
Debug.WriteLine(#"Register error: {0}", ex.Message);
}
*/
Hub = new SBNotificationHub(Constants.ConnectionString, Constants.NotificationHubName);
Hub.UnregisterAllAsync(deviceToken, (error) => {
if (error != null)
{
Console.WriteLine("Error calling Unregister: {0}", error.ToString());
return;
}
NSSet tags = new NSSet(); // create tags if you want
var expire = DateTime.Now.AddDays(90).ToString(); // set expire
try
{
//register native notification
Hub.RegisterNativeAsync(deviceToken, tags, (errorCallback) =>
{
if (errorCallback != null)
Console.WriteLine("RegisterNativeAsync error: " + errorCallback.ToString());
});
//register template notification
Hub.RegisterTemplateAsync(deviceToken, "add_newbook_notification", templateBodyAPNS, expire, tags, (errorCallback) => {
if (errorCallback != null)
Console.WriteLine("RegisterNativeAsync error: " + errorCallback.ToString());
});
}
catch (System.Exception ex)
{
Debug.WriteLine(#"Register error: {0}", ex.Message);
}
});
}
Because there could be multiple notification registration in one client app, theoretically both native and template notification registration should succeed here. However, I only receive the APNS but no template.

Azure Messaging - RegisterTemplateAsync isn't working? This link solves my problem.
Note:
The problem was that this ExpiryTemplate wasn't clear for me. I did find any docs on that one, but apparently, it's a DateTime formatted
as en-us.
The expiry datetime MUST be formatted as en-us. Otherwsie, the RegisterTemplateAsync can't work.

Related

Updating Azure SBNotificationHub tags after initial registration

I have a Xamarin Forms App which registers for notifications fine for iOS via the AppDelegate and the RegisteredForRemoteNotifications method. I have a tag I register here as well.
I was looking to have user settings to be able to update the tag registered. So as a test, I create a Dependency Service taking the Device Token and tag.
public async void UpdateTags(string token, string tag)
{
NSData deviceToken = new NSData(token, NSDataBase64DecodingOptions.None);
Hub = new SBNotificationHub(Constants.ListenConnectionString, Constants.NotificationHubName);
string[] SubscriptionTags = { tag };
var tags = new NSSet(SubscriptionTags.ToArray());
Hub.UnregisterAll(deviceToken, (error) =>
{
if (error != null)
{
Debug.WriteLine($"Unable to call unregister {error}");
return;
}
Hub.RegisterNative(deviceToken, tags, (errorCallback) =>
{
if (errorCallback != null)
{
Debug.WriteLine($"RegisterNativeAsync error: {errorCallback}");
}
});
var templateExpiration = DateTime.Now.AddDays(120).ToString(System.Globalization.CultureInfo.CreateSpecificCulture("en-US"));
Hub.RegisterTemplate(deviceToken, "defaultTemplate", Constants.APNTemplateBody, templateExpiration, tags, (errorCallback) =>
{
if (errorCallback != null)
{
if (errorCallback != null)
{
Debug.WriteLine($"RegisterTemplateAsync error: {errorCallback}");
}
}
});
});
}
This method runs correctly and the hub referred to here has the updated tags but the app seems to hold on to the old tag.
Do I need to refer to the original Hub created in the RegisteredForRemoteNotifications method in AppDelegate.cs?
Or is this the wrong approach? Long story short I need to update tags created via the RegisteredForRemoteNotifications method in AppDelegate.cs on app load.
Thank you!

Xamarin Forms: Android Phone contacts is not listing

I am referring to this blog for listing the phone contacts. It is working fine on the ios part but on android part, the contacts are not listing. There are no exceptions or errors but the UI is blank.
As per the blog I have done the below things on the android platform:
created the model class Contact and interface IContactsService.
Added READ_CONTACTS permission and added ContactsService implementation.
Installed Plugin.CurrentActivity and Acr.UserDialogs packages.
Added Permission.Util class into the Android project.
Added required things on the MainActivity and ContactPage files on the Main project.
Don't know what I am missing on the android part, on ios it is working fine. On android, the contact permission is not asking during runtime. I manually add the permission from the app settings, but no luck. My Xamarin forms version: 4.8.0.1821
I am uploading a sample project here for reference.
Thanks in advance.
Got the answer from my Microsoft QA thread:
Android 10 does not use Android.Support.V4.Content.ContextCompat to request permission, so please use Xamarin.Essentials: Permissions to request runtime permission.
On ContactsViewModel.cs, add CheckAndContactsReadPermission()method in LoadContacts method like following code.
async Task LoadContacts()
{
try
{
await CheckAndContactsReadPermission();
await _contactService.RetrieveContactsAsync();
}
catch (TaskCanceledException)
{
Console.WriteLine("Task was cancelled");
}
}
public async Task<PermissionStatus> CheckAndContactsReadPermission()
{
var status = await Permissions.CheckStatusAsync<Permissions.ContactsRead>();
if (status == PermissionStatus.Granted)
return status;
if (status == PermissionStatus.Denied && DeviceInfo.Platform == DevicePlatform.iOS)
{
// Prompt the user to turn on in settings
// On iOS once permission has been denied it may not be requested again from the application
return status;
}
status = await Permissions.RequestAsync<Permissions.ContactsRead>();
return status;
}
On ContactsService.cs, change the LoadContactsAsync method like the following code.
async Task<IList<Contact>> LoadContactsAsync()
{
IList<Contact> contacts = new List<Contact>();
//var hasPermission = await RequestPermissionAsync();
//if (hasPermission)
//{
var uri = ContactsContract.Contacts.ContentUri;
var ctx = Application.Context;
await Task.Run(() =>
{
var cursor = ctx.ApplicationContext.ContentResolver.Query(uri, new string[]
{
ContactsContract.Contacts.InterfaceConsts.Id,
ContactsContract.Contacts.InterfaceConsts.DisplayName,
ContactsContract.Contacts.InterfaceConsts.PhotoThumbnailUri
}, null, null, $"{ContactsContract.Contacts.InterfaceConsts.DisplayName} ASC");
if (cursor.Count > 0)
{
while (cursor.MoveToNext())
{
var contact = CreateContact(cursor, ctx);
if (!string.IsNullOrWhiteSpace(contact.Name))
{
OnContactLoaded?.Invoke(this, new ContactEventArgs(contact));
contacts.Add(contact);
}
if (stopLoad)
break;
}
}
});
// }
return contacts;
}

PushSharp 4.0.10.0: HTTP/2-based Apple Push Notification service (APNs)

We use PushSharp 4.0.10 to send iOS Push Notifications:
https://github.com/Redth/PushSharp
Recently we recieved this email from Apple Developer:
"If you still send push notifications with the legacy binary protocol, it's time to update to the HTTP/2-based Apple Push Notification service (APNs) provider API. You'll be able to take advantage of great features, such as authentication with a JSON Web Token, improved error messaging, and per-notification feedback.
To give you additional time to prepare, the deadline to upgrade to the APNs provider API has been extended to March 31, 2021. We recommend upgrading as soon as possible, as APNs will no longer support the legacy binary protocol after this date."
My question is: Will PushSharp 4.0.10 still work after March 31, 2021?
There is a discussion about this but the thread was closed. But there are still some suggestions on this thread that you might want to try.
The Apple Push Notification service (APNs) will no longer support the legacy binary protocol as of November 2020
https://github.com/Redth/PushSharp/issues/923
**
EDIT - 25th March 2021
The deadline is close and #Ashita Shah asked some code snippet so I hope the following can save your time.
Add the following class dotAPNSService to your project. You can customise this structure according to your needs. Also I didn't focus the best of best coding C# standards when implementing my own push notification service. You can implement LINQ, Tasks async etc. I tested this dotAPNS library and it works perfectly fine. For Android you can still use PushSharp.
Before you implement the dotAPNSService helper class, get the following from your Apple developer account. The ApnsJwtOptions values should be:
BundleId - your app’s bundle ID. Should not include specific topics (i.e. com.myapp but not com.myapp.voip).
CertFilePath - path to the .p8 certificate you have downloaded from the Developer Center.
KeyId - The 10-character Key ID you obtained from your developer account
TeamId - The 10-character Team ID you use for developing your company’s apps. Obtain this value from your developer account.
public class dotAPNSService : IDisposable
{
public event EventHandler OnTokenExpiredHandler;
private ApnsJwtOptions options = null;
public dotAPNSService()
{
options = new ApnsJwtOptions()
{
BundleId = "com.xx.xxxx",
CertFilePath = "../../certificate.p8",
KeyId = "The_Key_Id",
TeamId = "The_Team_Id"
};
}
public void SendNotifications(String[] deviceTokens, String title, String body)
{
if (deviceTokens == null || deviceTokens.Length <= 0)
{
return;
}
if (String.IsNullOrEmpty(title))
{
return;
}
if (String.IsNullOrEmpty(body))
{
return;
}
// once you've gathered all the information needed and created an options instance, it's time to call
var apns = ApnsClient.CreateUsingJwt(new HttpClient(), options);
// start the process
foreach (String deviceToken in deviceTokens)
{
var push = new ApplePush(ApplePushType.Alert)
.AddAlert(title, body)
.AddToken(deviceToken);
Send(apns, push, deviceToken);
}
}
public void SendSilentNotifications(String[] deviceTokens)
{
try
{
if (deviceTokens == null || deviceTokens.Length <= 0)
{
return;
}
// once you've gathered all the information needed and created an options instance, it's time to call
var apns = ApnsClient.CreateUsingJwt(new HttpClient(), options);
// start the process
foreach (String deviceToken in deviceTokens)
{
var push = new ApplePush(ApplePushType.Background)
.AddContentAvailable()
.AddToken(deviceToken);
Send(apns, push, deviceToken);
}
}
finally
{
}
}
private void Send(ApnsClient apns, ApplePush push, String deviceToken)
{
try
{
var response = apns.SendAsync(push);
if (response.Result.Reason == ApnsResponseReason.Success)
{
// the notification has been sent!
}
else
{
Boolean removeToken = false;
switch (response.Result.Reason)
{
case ApnsResponseReason.BadDeviceToken:
removeToken = true;
break;
case ApnsResponseReason.TooManyRequests:
break;
}
// remove the token from database?
if (removeToken)
OnTokenExpired(new ExpiredTokenEventArgs(deviceToken));
}
}
catch (TaskCanceledException)
{
// ERROR - HTTP request timed out, you can use the deviceToken to log the error
}
catch (HttpRequestException ex)
{
// ERROR - HTTP request failed, you can use the deviceToken to log the error
}
}
protected virtual void OnTokenExpired(ExpiredTokenEventArgs args)
{
try
{
EventHandler handler = OnTokenExpiredHandler;
if (handler != null)
{
ISynchronizeInvoke target = handler.Target as ISynchronizeInvoke;
if (target != null && target.InvokeRequired)
target.Invoke(handler, new object[] { this, args });
else
handler(this, args);
}
}
catch (Exception ex)
{
}
}
}
These are the namespaces of the dotAPNSService helper class:
using System;
using System.ComponentModel;
using System.Net.Http;
using System.Threading.Tasks;
using dotAPNS;
In order to use the dotAPNSService helper on your project just pull the tokens from the database and then pass them to it. For instance, to send silent notifications:
public void SendScheduledSilentNotifications()
{
try
{
IList<User> users = _accountService.GetUsers(true);
if (users != null && users.Count > 0)
{
List<String> deviceTokens = new List<String>();
foreach (User user in users)
{
if (!String.IsNullOrEmpty(user.DeviceToken))
deviceTokens.Add(user.DeviceToken);
}
if (deviceTokens.Count > 0)
{
using (dotAPNSService service = new dotAPNSService())
{
service.OnTokenExpiredHandler += new EventHandler(OnTokenExpired);
service.SendSilentNotifications(deviceTokens.ToArray());
}
}
}
}
finally
{
}
}
To remove the expired tokens from the database you can use the following:
private void OnTokenExpired(object sender, EventArgs e)
{
if (e == null)
return;
if (e.GetType() == typeof(ExpiredTokenEventArgs))
{
var args = (ExpiredTokenEventArgs)e;
User user = _accountService.GetUserByDeviceToken(args.Token);
if (user != null)
{
user.DeviceToken = String.Empty;
Boolean success = !(_accountService.SaveUser(user) == null);
if (success)
// INFO - expired device token has been removed from database
else
// INFO - something went wrong
}
}
}
You can download the source code from here:
https://github.com/alexalok/dotAPNS
The API is now sending thousands of silent notifications at one time and there are no delays, crashes etc. Hope this code snippet helps and saves your time!

Push Notifications: notification text vs other data

I have a Xamarin.Forms app that receives push notifications. Upon receiving the notification, the user clicks on it, and the app processes data that comes with the notification, and acts accordingly. But I have an issue with iOS part of the app. Instead of user friendly notification text, it displays the data in json format, which is not intended for this purpose.
Here is how the notification is sent:
private static async Task SendTemplateNotificationsAsync(string json, ILogger log)
{
NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString(NotificationDispatcherConstants.FullAccessConnectionString, NotificationDispatcherConstants.NotificationHubName);
Dictionary<string, string> templateParameters = new Dictionary<string, string>();
foreach (var tag in NotificationDispatcherConstants.SubscriptionTags)
{
templateParameters["messageParam"] = json;
try
{
await hub.SendTemplateNotificationAsync(templateParameters, tag);
...
}
catch (Exception ex)
{
log.LogInformation($"Failed to send template notification: {ex.Message}");
}
}
}
Here are the constants:
public static string APNTemplateBody { get; set; } = "{\"aps\":{\"alert\":\"$(messageParam)\"}}";
public const string NotificationTokenKey = "NotificationTokenKey";
Here is how the notifications are processed in AppDelegate.cs:
[Export("userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:")]
public void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
{
completionHandler();
NSDictionary userInfo = response.Notification.Request.Content.UserInfo;
ProcessNotification(userInfo);
}
[Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
{
completionHandler(UNNotificationPresentationOptions.Sound | UNNotificationPresentationOptions.Alert);
NSDictionary userInfo = notification.Request.Content.UserInfo;
ProcessNotification(userInfo);
}
void ProcessNotification(NSDictionary options)
{
Task.Run(() =>
{
// make sure we have a payload
if (options != null && options.ContainsKey(new NSString("aps")))
{
// get the APS dictionary and extract message payload. Message JSON will be converted
// into a NSDictionary so more complex payloads may require more processing
NSDictionary aps = options.ObjectForKey(new NSString("aps")) as NSDictionary;
string payload = string.Empty;
NSString payloadKey = new NSString("alert");
if (aps.ContainsKey(payloadKey))
{
payload = aps[payloadKey].ToString();
}
if (!string.IsNullOrWhiteSpace(payload))
{
if (App.UserContext.IsEmployee)
{
App.NewCall(payload);
}
}
}
else
{
Debug.WriteLine($"Received request to process notification but there was no payload.");
}
});
}
App.NewCall(payload); is the code that makes the payload to be handled by the app, which is correct. But I don't want this payload to be displayed as the notification text. How can I set the text to something different and user-friendly?
You don't need to handle the message if you just want to show a default UI:
see step 12 in this doc, make sure your payload is in a right format:
void ProcessNotification(NSDictionary options, bool fromFinishedLaunching)
{
// Check to see if the dictionary has the aps key. This is the notification payload you would have sent
if (null != options && options.ContainsKey(new NSString("aps")))
{
//Get the aps dictionary
NSDictionary aps = options.ObjectForKey(new NSString("aps")) as NSDictionary;
string alert = string.Empty;
//Extract the alert text
// NOTE: If you're using the simple alert by just specifying
// " aps:{alert:"alert msg here"} ", this will work fine.
// But if you're using a complex alert with Localization keys, etc.,
// your "alert" object from the aps dictionary will be another NSDictionary.
// Basically the JSON gets dumped right into a NSDictionary,
// so keep that in mind.
if (aps.ContainsKey(new NSString("alert")))
alert = (aps [new NSString("alert")] as NSString).ToString();
//If this came from the ReceivedRemoteNotification while the app was running,
// we of course need to manually process things like the sound, badge, and alert.
if (!fromFinishedLaunching)
{
//Manually show an alert
if (!string.IsNullOrEmpty(alert))
{
var myAlert = UIAlertController.Create("Notification", alert, UIAlertControllerStyle.Alert);
myAlert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null));
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(myAlert, true, null);
}
}
}
}
If you want to use custom user interfaces, you can create a notification content extension and create your UI there.

Xamarin Forms: Push notification is not receiving to ios device

I have done the following things:
Created a project in FCM console and added ios project into it.
Downloaded the GoogleService-Info.plist and added it to the xamarin forms ios project directory and set the build action as Bundlesource.
On Info.plist enabled remote notification background mode.
Added FirebaseAppDelegateProxyEnabled in the app’s Info.plist file and set it to No.
Created a provisioning profile and distribution certificate and installed it into the keychain access. Also, mapped these certificates in the project options.
Uploaded .p12 certificate in FCM console.
Added codes for handling push notification in AppDelegate.cs.
My Code:
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate, IUNUserNotificationCenterDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App("",""));
RequestPushPermissionsAsync();
_launchoptions = options;
// Register your app for remote notifications.
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.RemoteMessageDelegate = 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();
return base.FinishedLaunching(app, options);
}
NSDictionary _launchoptions;
public override void OnActivated(UIApplication uiApplication)
{
base.OnActivated(uiApplication);
if (_launchoptions != null && _launchoptions.ContainsKey(UIApplication.LaunchOptionsRemoteNotificationKey))
{
var notfication = _launchoptions[UIApplication.LaunchOptionsRemoteNotificationKey] as NSDictionary;
PresentNotification(notfication);
}
_launchoptions = null;
}
async Task RequestPushPermissionsAsync()
{
var requestResult = await UNUserNotificationCenter.Current.RequestAuthorizationAsync(
UNAuthorizationOptions.Alert
| UNAuthorizationOptions.Badge
| UNAuthorizationOptions.Sound);
bool approved = requestResult.Item1;
NSError error = requestResult.Item2;
if (error == null)
{
if (!approved)
{
Console.Write("Permission to receive notification was not granted");
return;
}
var currentSettings = await UNUserNotificationCenter.Current.GetNotificationSettingsAsync();
if (currentSettings.AuthorizationStatus != UNAuthorizationStatus.Authorized)
{
Console.WriteLine("Permissions were requested in the past but have been revoked (-Settings app)");
return;
}
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}
else
{
Console.Write($"Error requesting permissions: {error}.");
}
}
public async override void RegisteredForRemoteNotifications(
UIApplication application, NSData deviceToken)
{
//if (deviceToken == null)
//{
// // Can happen in rare conditions e.g. after restoring a device.
// return;
//}
//Console.WriteLine($"Token received: {deviceToken}");
// Get current device token
var DeviceToken = deviceToken.Description;
if (!string.IsNullOrWhiteSpace(DeviceToken))
{
DeviceToken = DeviceToken.Trim('<').Trim('>');
}
Console.WriteLine($"deviceToken received: {deviceToken}");
Console.WriteLine($"DeviceToken received: {DeviceToken}");
// Get previous device token
var oldDeviceToken = NSUserDefaults.StandardUserDefaults.StringForKey("PushDeviceToken");
// Has the token changed?
if (string.IsNullOrEmpty(oldDeviceToken) || !oldDeviceToken.Equals(DeviceToken))
{
//TODO: Put your own logic here to notify your server that the device token has changed/been created!
}
// Save new device token
NSUserDefaults.StandardUserDefaults.SetString(DeviceToken, "PushDeviceToken");
await SendRegistrationToServerAsync(DeviceToken);
}
async Task SendRegistrationTokenToMainPRoject(NSData deviceToken)
{
MessagingCenter.Send<object, string>(this, "fcmtoken", deviceToken.ToString());
}
public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
{
Console.WriteLine($"Failed to register for remote notifications: {error.Description}");
}
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo,
Action<UIBackgroundFetchResult> completionHandler)
{
PresentNotification(userInfo);
completionHandler(UIBackgroundFetchResult.NoData);
try
{
UIApplication.SharedApplication.ApplicationIconBadgeNumber = 0;
NSDictionary aps = userInfo.ObjectForKey(new NSString("aps")) as NSDictionary;
var message = (aps[new NSString("webContentList")] as NSString).ToString();
LoadApplication(new App("", message));
}
catch (Exception ex)
{
//LogInfo.ReportErrorInfo(ex.Message, ex.StackTrace, "AppDelegate-DidReceiveRemoteNotification");
}
}
void PresentNotification(NSDictionary userInfo)
{
NSDictionary aps = userInfo.ObjectForKey(new NSString("aps")) as NSDictionary;
var msg = string.Empty;
if (aps.ContainsKey(new NSString("alert")))
{
msg = (aps[new NSString("alert")] as NSString).ToString();
}
if (string.IsNullOrEmpty(msg))
{
msg = "(unable to parse)";
}
MessagingCenter.Send<object, string>(this, App.NotificationReceivedKey, msg);
}
}
I am not using any NuGet packages in ios part. When running the project into a device, the FCM token generating part is working and I can see the fcm token on the VS console. I tried to send a test notification to a device from postman but getting InvalidRegistration error.
Postman Response
{
"multicast_id": 8754155136812875313,
"success": 0,
"failure": 1,
"canonical_ids": 0,
"results": [
{
"error": "InvalidRegistration"
}
]
}
Postman Body
{
"to" : "d20ad003 7473bfba 85dffc33 1534decf b4b886f1 c738878f fd7f2c60 d9dabc36",
"collapse_key" : "type_a",
"data" : {
"body" : "Body of Your Notification in Data",
"title": "Title of Your Notification in Title",
"key_1" : "Value for key_1",
"key_2" : "Value for key_2"
},
"notification" : {
"body" : "Body of Your Notification",
"title": "Title of Your Notification",
"sound": "default",
"content_available" : true
}
}
I have completed the android part implementation and notifications are receiving when push from the postman. But getting InvalidRegistration error on ios part and not receiving any notification in my ios device.
I follow this youtube video for this implementation and the complete source code is here.
Anyone suggest a solution for this issue.
Thanks in advance.
Update
I have created a sample project and a postman collection and added it to my google folder.
Postman collection contains 2 REST APIs, one for Android device and the other one for ios device
If you import the postman collection and run the Android REST API, I will receive the notification, because I have added my device FCM token on it. But when running the ios REST API in postman will return InvalidRegistration error in postman.
Please go through the sample project and please give me a solution?
I have reviewed and can resolve this issue.
Install the plugin Xamarin.Firebase.iOS.CloudMessaging in iOS project.
AppDelegate class needs to inherit from IUNUserNotificationCenterDelegate and IMessagingDelegate interfaces.
Include the Firebase.Core.App.Configure (); in FinishedLaunching method before registering remote notification.
Then you can add the registering remote notification code (You can get the code from given link).
You need to set user notification delegate and messaging shared instant delegate (UNUserNotificationCenter.Current.Delegate = this; // For iOS 10 display notification (sent via APNS) and Messaging.SharedInstance.Delegate = this;).
Include DidReceiveRegistrationToken and DidReceiveMessage methods with corresponding attributes
Please refer this AppDelegate class for more clarity https://github.com/xamarin/GoogleApisForiOSComponents/blob/master/Firebase.CloudMessaging/samples/CloudMessagingSample/CloudMessagingSample/AppDelegate.cs
Related Xamarin Forums thread
https://forums.xamarin.com/discussion/159477/xamarin-forms-push-notification-is-not-receiving-to-ios-device#latest

Resources