react-native-onesignal
react-native-onesignal copied to clipboard
[Bug]: Could not invoke OneSignal.addPermissionObserver
What happened?
I have installed in an Expo app with
SDK49.0.9 and
custom expo 'dev-client'. Installed react-native-onesignal with onesignal-expo-plugin.
I only call in 'App.tsx' OneSignal.initialize('XXXX')
And I get an error could not invoke OneSignal.addPermissionObserver on start up.
Steps to reproduce?
1. Create an expo app with SDK 49.0.9 and build a custom dev-client for android
2. expo install onesignal-expo-plugin
3. yarn add react-native-onesignal
4. edit app.json
"plugins": [["onesignal-expo-plugin", {mode: "development"}]]
5. In App.ts
import {LogLevel, OneSignal} from 'react-native-onesignal';
OneSignal.Debug.setLogLevel(LogLevel.Verbose);
OneSignal.initialize('XXXXX');
Run the dev client
What did you expect to happen?
I expected the app to run and not crash on start up.
React Native OneSignal SDK version
5.0.0
Which platform(s) are affected?
- [ ] iOS
- [X] Android
Relevant log output
I get a screen in expo dev client stating:
There was a problem loading the project.
This development build encountered the following error:
Could not invoke OneSignal.addPermissionObserver
null
Must call with 'initWithContext' before use
invoke
JavaMethodWrapper.java
invoke
JavaModuleWrapper.java
run
NativeRunnable.java
handleCallback
Handler.java
dispatchMessage
Handler.java
dispatchMessage
Handler.java
loopOnce
Looper.java
loop
Looper.java
run
MessageQueueThredImpl.java
run
Thread.java
Code of Conduct
- [X] I agree to follow this project's Code of Conduct
The API has changed in the 5.x version.
Try using
OneSignal.Notifications.addEventListener("permissionChange", enabled => {
console.log("Notifications Enabled: ", enabled)
})
You might have to re-build the native apk file as well.
Thanks, @Codesane for linking to the new method!
@killerchip please feel free to refer to our migration guide for an overview of all the changes in 5.0.0.
Let us know if you have any additional questions or concerns!
@jennantilla @Codesane My problem still remains... I don't even use the 'addEventListener', I just add the following lines in my App.tsx
OneSignal.Debug.setLogLevel(LogLevel.Verbose);
OneSignal.initialize('XXXXX');
And I get the error.
I'm no Android expert, but I think the issue is somewhere there: indext.ts:
export function initialize(appId: string) {
if (!isNativeModuleLoaded(RNOneSignal)) return;
RNOneSignal.initialize(appId);
_addPermissionObserver();
_addPushSubscriptionObserver();
}
The RNOneSignal.initialize native function is supposed to initialize and run 'initWithContext'.
But either this does not happen, or there's a race condition, and 'initWithContext' is not called when the _addPremissionObserver() is called.
Has my suspicion any logical base? or am I looking into the wrong direction?
In fact I added a couple of logging in the function above, and created a log files from 'adb logcat'.
I can see that the _appPermissionObserver() is called before the initWithContext is called on the native level, for some reason.
Thanks, @Codesane for linking to the new method!
@killerchip please feel free to refer to our migration guide for an overview of all the changes in 5.0.0.
Let us know if you have any additional questions or concerns!
@jennantilla Thanks for the info and can you add this info in the official docs
@killerchip I am not able to reproduce this issue. Which verison of the onesignal-expo-plugin and react-native-onesignal are you using?
@killerchip I am not able to reproduce this issue. Which verison of the onesignal-expo-plugin and react-native-onesignal are you using?
Hi @emawby , apologies for the late reply. I'm using react-native-onesignal: ^5.0.0 and onesignal-expo-plugin: ^2.0.0
and from my yan.lock I see that those versions exactly resolved.
Gettings Must call 'initWithContext' before use crashes.
Using "react-native-onesignal": "^5.0.2",
useEffect(() => {
OneSignal.initialize(ONE_SIGNAL_APP_ID);
OneSignal.Notifications.addEventListener('click', async (e) => {
console.log('OneSignal: notification click event:', e);
});
}, []);
};
Gettings
Must call 'initWithContext' before usecrashes. Using "react-native-onesignal": "^5.0.2",useEffect(() => { OneSignal.initialize(ONE_SIGNAL_APP_ID); OneSignal.Notifications.addEventListener('click', async (e) => { console.log('OneSignal: notification click event:', e); }); }, []); };
Facing this issue on Android suddenly. It used to work earlier
We are also getting this error. It seems like there is a race condition when you call initialize and then try to call a OneSignal method.
For further context: This is happening on Android in particular - maybe related to: https://github.com/OneSignal/react-native-onesignal/issues/1554.
Example Code for initialization
const handleIngredientChangeNotification = useCallback(() => {
presentScreen(RootScreen.Inbox);
oneSignalService.setTagToTrue('hasOpenedIngredientChangeAlert');
}, []);
const handleNotification = useCallback(
(notification: OSNotification) => {
if (notification.additionalData) {
const { type } = notification.additionalData as NotificationData;
switch (type) {
case NotificationEventType.IngredientChangeEvent:
handleIngredientChangeNotification();
}
}
},
[handleIngredientChangeNotification],
);
const didReceiveOpenNotificationHandler = useCallback(
(event: NotificationClickEvent) => {
// Handle the notification after delivery from the background
handleNotification(event.notification);
analyticsService.logPushNotificationEvent(
AnalyticsEvent.PushNotificationOpened,
{
notificationId: event.notification.notificationId,
templateId: event.notification.templateId ?? '',
type: PushNotificationEventType.IngredientChangeNotification,
},
);
},
[handleNotification],
);
const didReceiveForegroundNotification = (
event: NotificationWillDisplayEvent,
) => {
event.preventDefault();
const notification = event.getNotification();
notification.display();
analyticsService.logPushNotificationEvent(
AnalyticsEvent.PushNotificationShownInForeground,
{
notificationId: notification.notificationId,
templateId: notification.templateId ?? '',
},
);
};
useEffect(() => {
// OneSignal Init Code
oneSignalService.initialize(ONESIGNAL_APP_ID);
OneSignal.Debug.setLogLevel(LogLevel.Verbose);
const promptForPush = async () => {
if (await OneSignal.Notifications.canRequestPermission()) {
OneSignal.Notifications.requestPermission(false);
}
};
promptForPush();
// Method for handling notifications opened
OneSignal.Notifications.addEventListener(
'click',
didReceiveOpenNotificationHandler,
);
OneSignal.Notifications.addEventListener(
'foregroundWillDisplay',
didReceiveForegroundNotification,
);
return () => {
OneSignal.Notifications.removeEventListener(
'click',
didReceiveOpenNotificationHandler,
);
OneSignal.Notifications.removeEventListener(
'foregroundWillDisplay',
didReceiveForegroundNotification,
);
};
}, [didReceiveOpenNotificationHandler]);
We are getting an error on the addTag method. This can be resolved by adding a setInterval ar
Example call to addTag
/**
* Calls provided function when this service has been initialized
*
* @param onSafe function to call
*/
private safeCall = (onSafe: () => void, maxTries: number = 1) => {
if (this.initialized) {
onSafe();
} else if (maxTries > 0) {
console.log(`waiting on onesignal`);
let tries = 0;
const callTimer = setInterval(() => {
tries++;
if (this.initialized) {
clearInterval(callTimer);
onSafe();
} else if (tries >= maxTries) {
clearInterval(callTimer);
logError('exceeded maxTries for OneSignalService safeCall');
}
}, 500);
} else {
logError('OneSignalService not initialized');
}
};
On my case the error comes because the constant of onesignalAppId is undefined when i use with Constants.expoConfig.extra.oneSignal App Id,
Im solved using process.env OneSignal.initialize( Constants.expoConfig.extra.oneSignalAppId || process.env.EXPO_PUBLIC_ONESIGNAL_APP_ID )
@tonyjimena I am not able to reproduce that issue. Were you able to get around it? Are you sure the app id was defined in the config properly?
closing for inactivity. If this is still an issue please tag and I can reopen