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

[Bug]: Could not invoke OneSignal.addPermissionObserver #1552

Closed
2 of 3 tasks
killerchip opened this issue Sep 7, 2023 · 14 comments
Closed
2 of 3 tasks

[Bug]: Could not invoke OneSignal.addPermissionObserver #1552

killerchip opened this issue Sep 7, 2023 · 14 comments

Comments

@killerchip
Copy link

killerchip commented Sep 7, 2023

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
  • 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

  • I agree to follow this project's Code of Conduct
@Codesane
Copy link

Codesane commented Sep 7, 2023

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.

@jennantilla
Copy link
Contributor

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!

@killerchip
Copy link
Author

killerchip commented Sep 11, 2023

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

@killerchip
Copy link
Author

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.

@emawby emawby reopened this Sep 12, 2023
@evo-sampath
Copy link

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

@emawby
Copy link
Contributor

emawby commented Sep 21, 2023

@killerchip I am not able to reproduce this issue. Which verison of the onesignal-expo-plugin and react-native-onesignal are you using?

@killerchip
Copy link
Author

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

@KestasVenslauskas
Copy link

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);
    });
  }, []);
};

@karthick-dmg
Copy link

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);
    });
  }, []);
};

Facing this issue on Android suddenly. It used to work earlier

@mljlynch
Copy link

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.

@mljlynch
Copy link

mljlynch commented Dec 20, 2023

For further context: This is happening on Android in particular - maybe related to: #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');
    }
  };

@tonyjimena
Copy link

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
)

@emawby
Copy link
Contributor

emawby commented Jul 17, 2024

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

@emawby
Copy link
Contributor

emawby commented Jul 23, 2024

closing for inactivity. If this is still an issue please tag and I can reopen

@emawby emawby closed this as completed Jul 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants