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?
Please list the steps used to reproduce your issue.
react-native infoEnvironment:
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
pod --versionHi @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.
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
Thank you @oskaratcodedesign, will update the docs.
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:
[AppCenterReactNativePush register]; if we don't have permission yet.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?
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.
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.
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.
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).
@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.
@JasonFehr Unfortunately there is no way to detect user selections on permission dialog.
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.
@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?
The feature is released in 1.11.0. It works differently than the workarounds.
The documentation is being published but here is a copy:
If you want to delay requesting Push notifications permission the first time the application is run:
EnablePushInJavascript as a Boolean property.YES.Push.setEnabled(true).After calling Push.setEnabled(true) once, the Push service will be started automatically the next time the application restarts.
If you want to delay Push initialization the first time the application is run:
, "enable_push_in_javascript": true before the last } of the file.Push.setEnabled(true).After calling Push.setEnabled(true) once, the Push service will be started automatically the next time the application restarts.
Most helpful comment
Proposed workaround (let me know if you see any issues with it):
In
ios/App/AppDelegate.m, comment out:Create
ios/modules/RegisterPushNotifications.h:Create
ios/modules/RegisterPushNotifications.m:Add the two files to your Xcode project. For an app named "Foo":
Task is now moved to the JS side of things, ideally you'd check with
AsyncStorageat launch if the user was prompted for permission or not.I would like to see this supported out of the box, such an essential feature.