Appcenter: Xamarin Forms Push.PushNotificationReceived Event - no way to know whether it was clicked or received in foreground

Created on 10 Apr 2019  路  30Comments  路  Source: microsoft/appcenter

Description

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.

Repro Steps

Please list the steps used to reproduce your issue.

  1. Set up App Center Push Notifications
  2. Run Xamarin Forms iOS Application
  3. Send Push Notification from App Center
  4. PushNotificationReceived Event fires because it is in the foreground
  5. Press Home button on device
  6. Send Push Notification from App Center
  7. Click on Push Notification on Device
  8. PushNotificationReceived Event fires because it is clicked
  9. How do you determine either of these scenarios because they will most likely want a different action to occur

Details

  1. What is your app platform (Xamarin.Android or Xamarin.iOS or UWP)?

    • Xamarin.Forms (3.6) > iOS app

  2. If using Xamarin.Forms or if using portable/shared code to call our SDK APIs, are you using shared project, PCL code or .NET standard code for the application? Which .NET standard version or which PCL profile?
    NET standard 2.0.
  3. Which SDK version are you using?

    • 1.14

  4. Which OS version did you experience the issue on?

    • iOS 12.2

  5. What device version did you see this error on? Were you using an emulator or a physical device?

    • iPod Touch

  6. What third party libraries are you using?

    • N/A

  7. Please enable verbose logging for your app using AppCenter.LogLevel = LogLevel.Verbose before your call to AppCenter.Start(...) and include the logs here:
    logs.txt
feature request push sdk

Most helpful comment

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

All 30 comments

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:

https://stackoverflow.com/questions/47756668/determine-if-app-is-in-foreground-upon-receiving-a-push-notification/57090389#57090389

@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.

Was this page helpful?
0 / 5 - 0 ratings