Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support delay push notification permission dialog #287

Closed
oskaratcodedesign opened this issue Apr 20, 2018 · 13 comments
Closed

Support delay push notification permission dialog #287

oskaratcodedesign opened this issue Apr 20, 2018 · 13 comments

Comments

@oskaratcodedesign
Copy link

We want to delay AppCenterReactNativePush register, so notification permission is not asked at startup. But it doesnt work:

if Push.setListener({onPushNotificationReceived: pushNotification => {
is called before AppCenterReactNativePush register is finished =
Crash AppCenterPushNotificationReceived is not a supported event type for AppCenterReactNativePush. Supported events are: (null)

AppCenterReactNativePush needs to be initialized?

Repro Steps

Please list the steps used to reproduce your issue.

  1. Dont call [AppCenterReactNativePush register]
  2. Call Push.setListener({onPushNotificationReceived: pushNotification => { })
    or
  3. Call [AppCenterReactNativePush register] (eg make a bridge and call it form react js)
    and call Push.setListener({onPushNotificationReceived: pushNotification => { })
    = either crash or onPushNotificationReceived is never received.
    or
    1 If you delay the Push.setListener({onPushNotificationReceived: pushNotification => { }), it doesnt crash, but then onPushNotificationReceived is never received?

Details

  1. Which SDK version are you using?
    • appcenter-push@^1.4.0:
  2. Which OS version did you experience the issue on?
    • iOS
  3. What device version did you see this error on? Were you using an emulator or a physical device?
    • iPhone X physical device
  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.4
Node: 9.3.0
Yarn: 1.3.2
npm: 5.6.0
Watchman: 4.9.0
Xcode: Xcode 9.3 Build version 9E145
Android Studio: 3.0 AI-171.4443003

Packages: (wanted => installed)
react: ^16.3.0-alpha.1 => 16.3.0-alpha.1
react-native: 0.54.2 => 0.54.2

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

dhei commented Apr 20, 2018

Hi @oskaratcodedesign,

Thanks for getting in touch. Unfortunately delaying the register of AppCenterReactNativePush is not supported in react native sdk now. Basically [AppCenterReactNativePush register] needs to happen in AppDelegate before JS loads, so in your repro steps Push.setListener in JS won't work because it's not registered. We are aware of this limitation and let's keep this open as a feature request for tracking. Unfortunately we don't have an ETA for this. Sorry for the inconvenience.

@dhei dhei changed the title Crash AppCenterPushNotificationReceived is not a supported event type for AppCenterReactNativePush. Supported events are: (null) Support delay push notification permission dialog Apr 20, 2018
@oskaratcodedesign
Copy link
Author

ok. You should probably: remove:
That call is added automatically to AppDelegate.m by the automatic instructions above. Otherwise, you need to add it manually.

Note that when the app calls register for the first time after being installed, iOS will prompt the user for permission to receive push notifications. If you wish to delay when that permission prompt appears to the user, say until after an app first time use wizard finishes, delay making the register call.
https://docs.microsoft.com/en-us/appcenter/sdk/push/react-native-ios

@dhei
Copy link
Member

dhei commented Apr 23, 2018

Thank you @oskaratcodedesign, will update the docs.

@codybrouwers
Copy link

This is a feature I need as well, it doesn't make sense for us to show a push notification permission request as the very first thing a new user sees in our app, we want to explain why they should allow us to send them notifications. Most apps operate that way so I'm surprised this isn't something already built into the SDK.

Do you think it would be possible to do the following:

  1. Skip calling [AppCenterReactNativePush register]; if we don't have permission yet.
  2. Use the built in Push Notification API to request permission.
  3. Next time the app loads, if we have permission then register AppCenterReactNativePush.

The downside to this is the user will not get push notifications until they or iOS has closed the app sometime in the future and the user has restarted it.

Could that potentially work in the meantime?

@dhei
Copy link
Member

dhei commented Apr 30, 2018

Hey @codybrouwers,

Thanks for getting in touch. What you suggested sounds like a good workaround with the caveat that user won't get push notifications between the time requestPermissions call and the [AppCenterReactNativePush register] on the next time app starts.

@sonaye
Copy link

sonaye commented Sep 4, 2018

Proposed workaround (let me know if you see any issues with it):

In ios/App/AppDelegate.m, comment out:

// #import <AppCenterReactNativePush/AppCenterReactNativePush.h>
// [AppCenterReactNativePush register];  // Initialize AppCenter push

Create ios/modules/RegisterPushNotifications.h:

#import <React/RCTBridgeModule.h>

@interface RegisterPushNotifications : NSObject <RCTBridgeModule>
@end

Create ios/modules/RegisterPushNotifications.m:

#import "RegisterPushNotifications.h"

#import <AppCenterReactNativePush/AppCenterReactNativePush.h>

@implementation RegisterPushNotifications

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(register)
{
  [AppCenterReactNativePush register];
}

@end

Add the two files to your Xcode project. For an app named "Foo":

Xcode > Project Navigator > Foo (blue) > Foo (yellow) > Add Files to "Foo"...

Task is now moved to the JS side of things, ideally you'd check with AsyncStorage at launch if the user was prompted for permission or not.

import { AsyncStorage, NativeModules } from 'react-native';

import Push from 'appcenter-push';

export const registerPushNotifications = async () => {
  const shouldRegister = await AsyncStorage.getItem('shouldRegister');

  if (shouldRegister) {
    NativeModules.RegisterPushNotifications.register();

    Push.setListener({ /* .. */ });
  }
};

export const askForPushNotificationsPermission = async () => {
  await AsyncStorage.setItem('shouldRegister', 'yes');

  registerPushNotifications();
};

// appDidMount
componentDidMount() {
  registerPushNotifications();
}

<Button title="Hi" onPress={askForPushNotificationsPermission} />

I would like to see this supported out of the box, such an essential feature.

@guperrot
Copy link
Member

guperrot commented Sep 7, 2018

We unfortunately don't have an ETA for this feature request but I forwarded this feedback to the team.

The solution looks good to me for iOS.

For Android, there should not be this UI as the custom module is undefined in the proposed solution so make sure this code is used only on iOS.

@sonaye
Copy link

sonaye commented Sep 8, 2018

Yes this is iOS only, already deployed and tested, it works great. I can add that It make sense to have it follow the same convention similar to Automatic/JS options in Analytics and Crashes, to avoid breaking the current implementation (Automatic only).

@JasonFehr
Copy link

@sonaye 's solution is fantastic, works great for me.

Still, it would be nice to have control over how permission is requested, not just when.

Is there a way to know whether the user clicked "yes" when prompted for permission? I have my app structured so that the user clicks "allow push" with a button I created, the app then calls AppCenterReactNativePush using @sonaye 's solution. This clumsily requires the user to click "allow" a second time in the alert message, but I guess that will do.

But, if she clicks "no" in this dialogue, do I have some way of knowing this? If she clicks "allow" in my app, then changes her mind and clicks "no" in the alert, things could get very confusing.

@jaeklim
Copy link
Contributor

jaeklim commented Sep 13, 2018

@JasonFehr Unfortunately there is no way to detect user selections on permission dialog.

@guperrot
Copy link
Member

You can actually check if notifications are enabled with what options.
Even after the user says yes or no in the system dialog, the user can still go the settings and enable/disable alert/audio etc so the dialog is not final.
You can check what notifications flags are enabled by using this stackoverflow answer.

@ghost
Copy link

ghost commented Dec 4, 2018

@sonaye - thank you for the solution to iOS! Did you also solve it for Android or do you have an idea how to do it?

@guperrot
Copy link
Member

guperrot commented Dec 17, 2018

The feature is released in 1.11.0. It works differently than the workarounds.

The documentation is being published but here is a copy:

iOS

If you want to delay requesting Push notifications permission the first time the application is run:

  • Open Xcode, and edit the ios/{APPNAME}/AppCenter-Config.plist file.
  • Add EnablePushInJavascript as a Boolean property.
  • Change the value to YES.
  • Once you get approval from the user to use Push at runtime, call Push.setEnabled(true).

After calling Push.setEnabled(true) once, the Push service will be started automatically the next time the application restarts.

Android

If you want to delay Push initialization the first time the application is run:

  • Edit the android/app/src/main/assets/appcenter-config.json file.
  • Add , "enable_push_in_javascript": true before the last } of the file.
  • Once you get approval from the user to use Push at runtime, call Push.setEnabled(true).

After calling Push.setEnabled(true) once, the Push service will be started automatically the next time the application restarts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants