Shiny NotificationDelegate OnReceived not being called on iOS - xamarin.forms

We've been using Shiny framework for Local Notifications and it has done what we needed which is make a notification appear on iOS and Android that when tapped will open the app.
However the OnReceived method on the INotificationDelegate never gets called on iOS. This has been the case forever IIRC but was of no real concern as we didn't need to do anything with the OnReceived except track it in AppCenter. Therefore fixing it never got prioritised.
Recently we have been looking at using Push Notifications. We are not using Shiny's push and instead are registering the device using out our own backend WebApi.
I am seeing a problem where our AppDelegate override of ReceivedRemoteNotification does not get called if i call the UseNotifications extension in our ShinyStartup ConfigureServices. We want to continue using Shiny for Local Notifications so this is a problem.
I am wondering if the issue that means our local notification received delegate does not get called is related to this issue.

You are using ReceivedRemoteNotification which is for the "old" way of catching remote notifications in the foreground. Shiny.Notifications uses a UNUserNotificationCenterDelegate which I believe intercepts and stops that method. You can implement the Shiny notification delegate to work with the notification or use Shiny.Push.AzureNotificationHubs.
You can also use: DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action completionHandler) which is a better method to handle remote notifications anyhow since it is needed for background processing

Related

Firebase messaging background handler not called when app is terminated (Flutter)

I am trying to update my app's badge count number of my flutter app when receiving push notifications when the app is terminated.
The Firebase messaging background handler works fine if the app is in the background but doesn't work when the app is terminated.
I have read in the documentation :
On iOS, if the user swipes away the application from app Switcher, it must be manually reopened again for background messages to start working again.
Does it mean that on iOS there is no way to update the badge count using the firebase background handler (by the logic you implement in the handler of course, just need the handler to be called) ?
Any app do this today so i wonder why it would not be possible with Firebase Messaging.
I have actually found a solution, by using a service extension in swift and passing data as payload server side, using content-available: true in python.
Here is the documentation i have followed to implement the notification server side.
Also, there is an ongoing bug / feature request for flutter and Firebase regarding this case.

PUSH Notifications in Xamarin Forms with Microsoft.AppCenter

Q: I am using XAMARIN Forms with Microsoft.AppCenter. How do I get the firebase device ID using the AppCenter API for sending push notifications to my mobile clients (Android/IOS) from my backend?
Frontend (Requirements)
1. XAMARIN Forms
2. Microsoft.AppCenter
3. Microsoft.AppCenter.Push
4. MUST use AppCenter to get the FireBase deviceID.
5. AppCenter.GetInstallIdAsync() will not work for my backend. I need the FireBaseDeviceID
6.
Backend (Requirements)
1. I must make the call using FireBase’s https://fcm.googleapis.com/fcm/send POST request.
I have a backend server that needs to send the push directly to firebase. NOT thru AppCenter. I need firebase’s DeviceID for each device I want to send to. I have it working for pushing to all devices for my app. But I also need to go to a specific device that was registered thru AppCenter. This is why I need my front end apps to get the FireBase DeviceID for the PUSH.
You don't have the possibility to get Firebase id from using AppCenter.
You have two ways out of this:
1. Skip using AppCenter for pushes in your app. You'd have to implement interaction with Firebase on each platform you support according to documentation. I can share more tips if you choose this option.
2. Convince backend team to use AppCenter API to send individual push notifications https://openapi.appcenter.ms/#/push/Push_Send
I know each of these solutions contradicts one of your requirements. But you'd have to choose only one push service, either AppCenter or Firebase, for your project and stick with it. Personally I vote for Firebase, learned it the hard way.
UPDATED
Most of the time, Firebase documentation is your best friend when switching to FCM.
On the app side:
Setting up Firebase client for iOS and for Android.
Some tricks from my experience:
Android:
You'll have to listen to Firebase InstanceID changes in a descendant of FirebaseMessagingService and store it for later use. It's not available whenever you need it as it is with AppCenter.
My activity has LaunchMode = LaunchMode.SingleTopand I override two methods to handle push depending on app state when it arrived: void OnNewIntent(Intent intent) and void OnPostCreate(Bundle savedInstanceState). It might not be your case because I handle silent pushes as well. To check if intent contains a push from Firebase run intent?.GetStringExtra("google.message_id") != null.
iOS:
Push notifications won't work on iOS simulators and initialization steps might crash your app when run on Simulator. I have created __IOS_SIMULATOR__ constant next to __IOS__ and DEBUG under Debug|iPhoneSimulator configuration in csproj file. And used it in AppDelegate.cs like this:
#if !__IOS_SIMULATOR__
new FirebaseCloudMessagingInitializer().Init();
#endif
AppDelegate offers two methods to override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo) and void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler). I used the first one at the beginning and faced edge cases when it was not called. So I had to switch to overriding the latter one. But don't follow this advice blindly, check what suits best for your needs.
Also, beware of https://github.com/firebase/firebase-ios-sdk/issues/2438, I'm not sure whether it was already fixed since I had to deal with it.
In case it is still there, apply the fix from https://github.com/firebase/firebase-ios-sdk/issues/2438#issuecomment-469472087
On backend side:
https://fcm.googleapis.com/fcm/send is so called legacy protocol, use HTTP v1 instead
POST https://fcm.googleapis.com/v1/projects/project_name/messages:send. Explore documentation.
How to authorize send request
How to compose push content

Firebase Cross Platform Push Notification Plugin Duplicating MainActivity

I'm using the following plugin for implementing and handling FCM push notifications in my xamarin application and there's one little unaddressed problem I'm facing.
I was hoping someone else has already figured it out and could help me.
THE PROBLEM:
It seems to be duplicating my MainActivity although I have the LaunchMode set to SingleTop.
There's an event called OnNotificationReceived that's provided by the library.
This event fires as expected, only once, when the application is in the foreground.
When I minimize the application (let it run in the background), send a notification to the device and tap on the notification, it opens the application, as expected, but if I send another notification after that, while the application is in the foreground, The OnNotificationReceived Event is fired twice.
I've tried changing the NotificationActivityFlags property to SingleTop.
I've tried changing my MainActivity's Launch Mode to SingleTop
I tried running the sample application they've provided to check if its something that I'm doing wrong, and still the same thing happens.
Logging the issue in their Github repository
None of the above have worked.
The issue can be reproduced by:
downloading the sample from the repository, link provided above
replacing their google-services.json file with your own from the Firebase
console.
change the package name of the sample of the application to the one you
have registered on Firebase
following the steps above that I've mentioned
ADDITIONAL INFO
Version Number of Plugin: 1.3.0
Device Tested On: Huawei P8 Lite Android Version 6.0
Version of VS: Visual Studio 2019
Version of Xamarin: 3.4.0.1009999
Update:
Unfortunately, the method below has not proven successful after attempting to implement it, I should have thought of the fact that I'm still going to need the notification object for iOS, earlier.
Myself and the team are going to implement a way to keep track of the users platform on the server and send them a notification either with or without the notification based on their platform, since iOS handles FCM notifications differently from Android. For now we're going to use Google's Instance ID service to determine what platform existing users are on.
Workaround:
I hope this helps someone in the future, if not I hope someone can provide me with a better solution.
In order to have my cake and eat it, basically be able to keep the notification object in the payload instead of removing it and having to further customise the payload to display notifications just for iOS, I changed the MainActivity's (the activity thats launched when a user taps on the notification) Launch mode to SingleInstance. That way I can keep my notification object in the payload and not have to worry about the OnNotificationReceived event being triggered twice.

How do you access OneSignal's database on Android & iOS in Flutter?

I am using OneSignal in my Flutter application to receive notifications. I have created my own table within Flutter to save notifications but I cannot save messages that have been sent whilst the app has been terminated. However, I have found that the OneSignal package has it's own database installed on the device which captures everything no matter what state the application is in! So, to avoid duplicating data I want to use this database instead. It is located outside of the flutter app folder which is my issue (see image below).
How do I access this database? Does anybody know if it is the same on iOS (I haven't been able to check at this time).
Many thanks.
It's important to understand that if an app has been terminated, any onReceived handler will not be fired. We don't recommend using the local db at all. Your best bet is to use the respective notification extender services for each platform. Though you will have to write native code for this! Cheers
Edit:
ANDROID - NotificationExtenderService - This can be setup to receive silent notifications when your app is not running or to override how notifications are shown in the notification shade. See the Background Data and Notification Overriding section to set this up.

Push notification to iOS not working when message received

I have a Worklight app doing push notifications. Sending the push causes the notification to appear in the notification bar on both Android and iOS as expected. If the push is received while the app is running, it calls the message handler function as it is supposed to.
The issue I'm having is that if you launch the app by tapping on the notification on iOS, the message handler never gets called if another push is sent while the app is running. I have to exit the app and kill it completely, then relaunch the app from the launcher. Then if the push is received while the app is running, it will call the message handler.
This only occurs on iOS. The app will respond to a received message on Android while the app is running, even if the app has been launched by tapping on the notification.
EDIT:
I did struggle to verbalize the scenario, couldn't find the right words that made sense, but the steps you have done Idan are largely correct for what I'm trying to do. We are doing tag based notifications, so that is different that what you have done. We are also using PersistentCookieAuthentication as they wanted push notifications to be sent without the user having to explicitly logging in.
We are currently using WL build 6.2.0.01-20141216-0427
We've tried it on a couple of different models, an iPhone 4s running 8.0.2, and an iPhone 5 running 8.1.2.
Edit based on the edited question:
Tag-based notifications do not require any login, as it is the device that is to be subscribed to any tags that you define in application-descriptor.xml; it is not login-based, so any type of login that you are doing it irrelevant. The push will be sent to any device (app...) that was subscribed to your tag using the subscribeTag API.
I did another test in iOS using a broadcast-based notification (it's basically like tag-based notifications). I kept the app in the background and sent a notification. Tapping on the incoming notification in the notification bar brought the app to the foreground, which then displayed the alerts of the incoming notification.
You can try it with this application: https://www.dropbox.com/s/l2yk2pbvykrzfoh/broadcastNotificationsTest.zip?dl=0
Make sure to place your own .p12 certificate and pushSender password.
I've been trying to understand your scenario... I suspect you've left out something or need to better word the problem description.
Here's what I've tried using MobileFirst Platform 6.3 (no drastic push changes in iOS between 6.2 and 6.3) and iPhone 6 running iOS 8.1.2.
Launched sample push notifications app (which uses event source-based notifications) on device
Logged-in > Subscribed
Quit application
I then sent a notification by invoking the adapter in the Studio
The notification arrived and displayed in the notification bar
Tapping the notification launched application
Logged-in
The notification alerts were then displayed.
I then moved the application to the background.
Sent another notification, which was displayed in the notification bar upon arrival
Tapping this second notification brought the application to the background, displaying the alerts
I then kept the application in the background.
Sent a third notification
In this case, because the application is in the foreground, the notification did not display in the notification bar -- as expected -- and instead the alerts were displayed right away.
If your scenario is different than the above, such as: you're not even using event source-based notifications but rather broadcast- or tag-based notifications, or your application flow differs, etc then please edit the question with a more precise description.
When you edit the question, also mention the following:
Worklight version and build number
Device model
Used iOS version
I am aware of one possible issue (APAR #PI31988) that is currently under investigation, where the underlying native code dispatches the message before the JavaScript framework is ready to handle it, thus no message is displayed. This was found to happen in slower devices such as iPhone 4.

Resources