Xamarin Forms Push.PushNotificationReceived Event - no way to know whether it was clicked or received in foreground. This even fires when receiving a Push Notification when the App is in the foreground and when a user clicks on it. There doesn't seem away to determine which of these occurred? If they clicked on it I want to navigate them to the relevant screen, if it is received in the foreground, at present, I want to do nothing.
Please list the steps used to reproduce your issue.
AppCenter.LogLevel = LogLevel.Verbose before your call to AppCenter.Start(...) and include the logs here:Hi @james1301, please see Xamarin Forms Push section.
Basically, when the push is clicked from background on Android and UWP, the event does not have title and message in the event arguments, only iOS expose those fields for all events. So one way of distinguishing this would be the message property.
Hi @annakocheshkova, I don't understand on iOS they seem exactly the same. How can I distinguish this? Reading the documentation doesn't help either that I am aware of.
Regardless something like a "Received Type" for this would simplify this, User Clicked, Foreground or Silent?
@james1301 for Xamarin iOS, you may want to implement this.
Oh sorry, didn't notice that you have an iOS app at the first look :)
Thanks @annakocheshkova I will take a look at that implementation.
Is there any plan to fix this in the future? Just having had a quick look at the link you suggested seems a little bit of a messy workaround when the recent API changes have moved away from having to use the iOS specific methods.
@james1301 not that I know of, unfortunately. And as far as I know there's no convenient way to distinguish between background/foreground notifications in React/Cordova apps, all the solutions we had so far looked like a workaround, too. But if you really-really want to do it inside React context, you can check this comment out.
So we decided not to implement it because this is not a very reliable way to do this. But you can use it, if you like this way better.
Hmmm @annakocheshkova, I see what you mean if all instances do not work the same, but it this just seems quite fundamental to me, and is very confusing. The documentation doesn't really spell out any of these problems either.
Could you not have a "ReceivedType" property added to PushNotificationReceivedEventArgs which is an enum with "UserClicked", "Foreground", "Silent" and "Unknown" for those application types it doesn't work with. Clarity is greatly increased, then your documentation you could have something for unknown saying for this type it is because of this, and you can do this etc?
Most platforms the documentation would not even be required because I would have just seen that and used it.
This is good point @james1301. I will check with my team to see if such implementation is possible.
imho this feature is super important.
Currently, in iOS, we need to implement a custom UNUserNotificationCenterDelegate and override WillPresentNotification and DidReceiveNotificationResponse in order to distinguish between background clicked or foreground notifications
Everything is working but we are missing a key advantage of Xamarin Forms: code reuse.
We need to reimplement, in the iOS platform code, the shared logic used for Android and UWP in the .NETStandard project.
iOS is providing all the necessary tools to distinguish between background clickend and foreground notifications, so Appcenter should pass that info to the Xamarin.Forms project
This is also we are having issues with. Would be greatly appreciated if PushNotificationReceivedEventArgs had a boolean telling if the notification was recieved in foreground or background.
PushNotificationReceivedEventArgs.DidRecieveInForeground or similiar.
@annakocheshkova Do you have a status on this request? Is this something we can expect in the near future?
Thanks in advance.
Do we have a status for this request? This would be great to have, as @shnaz mentioned "If PushNotificationReceivedEventArgs had a boolean telling if the notification was recieved in foreground or background."
As a workaround whilst we wait for this feature request, I am using the Application life cycle events to detect if the push notification is received either in the foreground or via an user tap as suggested in this article, https://stackoverflow.com/questions/47756668/determine-if-app-is-in-foreground-upon-receiving-a-push-notification. I haven't fully tested this approach, but seems to be working in the most cases that I have tested so far.
@SandipAhluwalia I am not sure if that workaround is 100% usable because when push notification is recieved and your app is in background. User will click on push notification and your app will be launched again, than it will go through the application lifecycle event OnResume() it will set the IsInForeground to true and it will fire the PushNotificationReceived... you will have IsInForeground equals to true, and that is not ok because you app was in background when push notification is received and user clicked on it. You can play around and you will get same kind of behaviour. So it will be more than helpful for us to know if notification was clicked or received in foreground. :)
I have update the stackoverflow question with my implementation of a custom UNUserNotificationCenter delegate that will handle the notification tapped event in the proper, native, way.
For now, I'm using MessagingCenter to notifiy the Xamarin.Forms project.
So far i found the best and reliable method to support notification tap using appcenter:
@almirvuk I agree with you as I am not convinced yet that the workaround is 100% full proof, but in my testing so far it seems to work... So I am using Prism framework and below are my observations with the standard life-cycle events.
My set up in App.xaml.cs:
protected async override void OnInitialized()
{
InitializeComponent();
if (!AppCenter.Configured)
{
Push.PushNotificationReceived += async (sender, e) =>
{
var pageDialogService = Container.Resolve<IPageDialogService>();
if (IsInForeground)
{
await pageDialogService.DisplayAlertAsync(e.Title, e.Message, AppResources.CancelBtnAlert);
}
...
}
Android:
App in Background (IsInForeground set to false in OnSleep() ) -> Send push notification -> Tap on notification -> Push.PushNotificationReceived is called with IsInForeground set to false -> OnInitialized() called again meaning app starts again for some unknown reason -> OnStart() called with IsInForeground set to true.
iOS:
App in Background (IsInForeground set to false in OnSleep() ) -> Send push notification -> Tap on notification -> Push.PushNotificationReceived is called with IsInForeground set to false -> OnResume() called with IsInForeground set to true.
So key difference above is that on iOS, the app resumes nicely, but on Android it is restarted after Push.PushNotificationReceived event is called. In both cases, the Push.PushNotificationReceived event is called first when app is in background and user taps on the push notification.
Naturally the workaround works as expected when you receive a push notification and the app is in the foreground. In my case, I display a modal dialog.
*UPDATE: Above is only true when app is in 'memory' background! When app launches from cold then above flag logic breaks down, so not a good workaround.*
@Evolutionlab Thank you for your solution, but it seems to me that it doesn't cover Android at all?
You are right, my solution is only for iOS because in Android with appcenter you can already know when a user tap a notification when the app is closed.
@Evolutionlab Out of interest, do you use the approach on Android where if you have no title and message in the event arguments then it means the notification arrived whilst in background? I am not happy with this approach as this logic may change in a future SDK update.
@SandipAhluwalia yes, for now i'm using the "no title and message" thing to detect the tap in Android. Is not a very good solution but for now it's enough for my use case.
Btw AppCenter should hadle this in much better ways, it should be a TOP priority, imho
@james1301 thank you for suggesting this, it鈥檚 on our roadmap, we鈥檙e planning features now.
@jwargo Thank you!
Any update, guys? Also, when a notification is clicked in the background, Android seems to restart the previous activity, so OnResume() is never called. When the tap occurs in the background, restarting everything seems to take a long time, so from a UX perspective, this is not a good experience at all.
For the time being, I set MainActivity to launch as a single task and started processing push events through
protected override void OnNewIntent(Android.Content.Intent intent)
{
base.OnNewIntent(intent);
Push.CheckLaunchedFromNotification(this, intent);
}
A singleton instance is used for MainActivity so I can continue getting OnResume updates. This seems to work for now.
Like others, I agree that we shouldn't use a hacky solution (e.g. message and title lookup on Android or a flag to determine app event lifecycle state). We need an actual property to rely on. :)
Thank you for suggesting this. We are aware of this need will add this request to our list of requested features. We track feature requests and announce our future plans on the AppCenter repo. Whenever you have a feature request, please post it there and vote on the ones you want.
Any news about this? :)
@almirvuk no, I'm sorry - it's on our roadmap and I'm planning the next few releases right now. I will have this in your hands as soon as I can.
Transferring this issue to AppCenter Central Repository where all the new feature requests are being tracked and prioritized. Thanks
Any updates? When will this feature be available?
Thank you very much for your feedback on App Center Push. We announced yesterday in a blog post that we鈥檙e retiring the Push service later this year and recommending customers transition to Azure Notification Hubs instead. The good news is that the same team operates both App Center Push and Azure Notification Hubs, so all customer feedback and feature requests have been transferred to the Azure Notification Hubs roadmap.
@jwargo very disappointing.
Most helpful comment
imho this feature is super important.
Currently, in iOS, we need to implement a custom
UNUserNotificationCenterDelegateand overrideWillPresentNotificationandDidReceiveNotificationResponsein order to distinguish between background clicked or foreground notificationsEverything is working but we are missing a key advantage of Xamarin Forms: code reuse.
We need to reimplement, in the iOS platform code, the shared logic used for Android and UWP in the .NETStandard project.
iOS is providing all the necessary tools to distinguish between background clickend and foreground notifications, so Appcenter should pass that info to the Xamarin.Forms project