Appcenter-sdk-react-native: How to differentiate between user clicked notification and foreground notification for iOS (content-available not set)

Created on 21 Aug 2018  路  15Comments  路  Source: microsoft/appcenter-sdk-react-native

Creating a new issue as was suggested to me since my old one was closed, which can be found here...

https://github.com/Microsoft/AppCenter-SDK-React-Native/issues/375

Very similar, the suggestions from that issue solved my android issue. But the iOS payload between automatically received event for foreground vs a user initiated click on a notification seems identical. The documentation seems to imply that it is possible, but I can't quite tell how. Thanks

Description

I'm having trouble seeing how you can determine whether a notification was received while the app was in the foreground or not. The behavior of the app is highly dependent on this information.

Repro Steps

Please list the steps used to reproduce your issue.

  1. Send push notification via the portal
  2. Debug application and see that there is no property for whether it was a user interaction or not

Details

  1. Which SDK version are you using?
    1.7.0
  2. Which OS version did you experience the issue on?
    iOS 11.3 and 11.4.1
  3. What device version did you see this error on? Were you using an emulator or a physical device?
    iPhone 6 plus and iPhone 8
  4. What third party libraries are you using?
  5. Run the following command and paste the output below: react-native info

Environment:
OS: macOS High Sierra 10.13.6
Node: 10.1.0
Yarn: 1.6.0
npm: 6.2.0
Watchman: 4.9.0
Xcode: Xcode 9.4.1 Build version 9F2000
Android Studio: 3.1 AI-173.4819257

Packages: (wanted => installed)
react: 16.3.1 => 16.3.1
react-native: 0.55.4 => 0.55.4

  1. If you're developing for React Native iOS, run the following command and paste the output below: pod --version

1.5.3

  1. Please enable verbose logging for your app using [MSAppCenter setLogLevel: MSLogLevelVerbose]; before your call to [AppCenterReactNative register]; (or any other SDK registration). For Android, use AppCenter.setLogLevel(android.util.Log.VERBOSE); before your SoLoader.init call. Include the logs here:
support

Most helpful comment

@FelipeGatti currently, there's no convenient way to do this except the solution described it the docs. If you want, you can follow @jdnichollsc's comment here on an alternative approach.

All 15 comments

Hey @buddhamangler

I think you can use AppState to determine if your app was in foreground or background when notification was received. There are a lot of discussions on StackOverflow regarding this problem, but basically, all solutions involve checking current application state.

Best,
Murat

Yes if AppState is background it means the notification was received in background. Though, @buddhamangler are you using silent notifications or classic notifications in iOS? iOS callbacks are executed in background for silent notifications only.

I think the question was to determine if the callback was executed because of a notification click or if it was received in foreground. The question does not look related to silent push.

@guperrot correct

@clpolet i am NOT using silent notifications. I just need to be able to differentiate between a foreground received notification and a notification triggered by clicking the notification in the notification area.

Surely this is a common scenario? I don't think AppState suggested above helps me.

Hey @buddhamangler,

The problem is that the AppCenter SDK itself does not expose individual callbacks but only the onPushNotificationReceived:-callback as described in https://docs.microsoft.com/en-us/appcenter/sdk/push/react-native-ios.

But there is a way for you to achieve what you want but you need to implement some of the callbacks that are defined in UNUserNotificationDelegate (https://developer.apple.com/documentation/usernotifications/unusernotificationcenterdelegate).

To achieve your scenario on iOS, you need to follow these steps:

  1. In your AppDelegate, add the following to the didFinishLaunching:withOptions: to register as a UNUserNotificationCenterDelegate:

    ```objc
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;

2. Implement the following callbacks for foreground notifications:

```objc
//iOS 10 and up, called when a notification is delivered to an app that is in the foreground.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
    NSLog(@"called userNotificationCenter:willPresentNotification:withCompletionHandler:");
     // Make sure to call the completionHanndler
     completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
  1. Implement the following callbacks for background notifications:
// Called when a notificationn is delivered to an app that is in the background or foreground.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    NSLog(@"called application:didReceiveRemoteNotification:fetchCompletionHandler:");
}
  1. As you probably have implemented the onPushNotificationReceived callback of App Center push to display your alert, you might want to make it do nothing for iOS and implement the logic to display an alert in your native iOS code.

@TroubleMakerBen Thank you for the detailed explanation! I will investigate this method. Right now I have been trying to make a pure react native solution work where i check the AppState as suggested above and if the state is background or an initial state i set in the constructor (which is overwritten in the react native pipeline which always occurs after the delivery of the notification) then i assume it was launched by the user. I really don't know if that's a good assumption yet, but it seems somewhat promising.

That sounds like it coulld work, too. Let us know how things go @buddhamangler.

Hi, we haven't heard from you in a while so I'm closing this issue. Please reopen/comment if you have more questions or run into this again.

Debugging the AppCenter listener from Android, AppCenter.currentState is always active, Do you know why?

The AppState.currentState should definitely be background when the notification is received in background. Once the user clicks on the notification (even if the notification was received in background) then the state shouldn't be background anymore.

is there any idea on some modification in the SDK to make this happen easier?
I'm planning on following @buddhamangler path but not sure if it's the correct way to go on.

@FelipeGatti currently, there's no convenient way to do this except the solution described it the docs. If you want, you can follow @jdnichollsc's comment here on an alternative approach.

Thank you @annakocheshkova for the rapid response! i will check this approach!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matthargett picture matthargett  路  7Comments

newyankeecodeshop picture newyankeecodeshop  路  4Comments

celso-henrique picture celso-henrique  路  9Comments

zzorba picture zzorba  路  8Comments

CyberMew picture CyberMew  路  4Comments