React-native-onesignal: onIds trouble

Created on 19 Feb 2017  ·  25Comments  ·  Source: OneSignal/react-native-onesignal

Hi i have OneSignalController that i include in Main.js

class OneSignalController extends Component {
    props: Props

    constructor(props) {
        super(props);
    }
    componentWillMount() {
        OneSignal.addEventListener('opened', this.onOpened);
        OneSignal.addEventListener('ids', this.onIds);
    }

    componentWillUnmount() {
        OneSignal.removeEventListener('opened', this.onOpened);
        OneSignal.removeEventListener('ids', this.onIds);
    }

    onIds = (device) => {
        this.props.dispatch_set_device_id(device.userId);
    }

    render() {
        return null;
    }
}

I use redux-persist and don't want to start the app before rehydration is done.
so i want to do this in my index.android.js

...
        this.state = { rehydrated: false };
    }

    componentWillMount() {
      Storage.restoreData(store, {}, () => {
        this.setState({ rehydrated: true });
        });
    }

    render() {
        return (
            this.state.rehydrated === true
            ? <Provider store={store}>
                <View style={styles.container}>
                    <Main />
                </View>
            </Provider>
            : null
        );
    }

But if i do oneSignal does not trigger the onIds function anymore.

Help Wanted

Most helpful comment

I just started using this lib and hit the same issue. Using redux-persist here too! And after some digging, I strongly believe it has to do with redux-persist. Or any delayed subscription to the ids event.

The following code, if put right in the index.xxx.js (i.e. very early in the app start), it will trigger on every app restart:

//... other imports
import OneSignal from "react-native-onesignal";

OneSignal.addEventListener('ids', (device) => {
    console.log("[OneSignal]>>ids: ", device);
});

// ....

AppRegistry.registerComponent ....

However, if the OneSignal.addEventListener('ids' ... is called after redux-persist rehydration => kiss the callback goodbye.

FIX here's how I (hack?)fixed it, for now (current react-native-onesignal release 3.0.3):

there is an undocumented js-side method called OneSignal.configure() that makes the native side (android and ios) to broadcast the ids event back to the js-side.

So, call it right after adding the event listener for 'ids':

// ... after store rehydration complete ...

OneSignal.addEventListener('ids', (device) => {
   // ... do whatever with device
});

OneSignal.configure();  // add this to trigger `ids` event

By my assessment of how it's implemented in the native side and it seems to be pretty safe to call that, even more than one time (it just replaces the internal event handler, doesn't create more). But keep in mind, it fires the ids listeners each time.

I now wonder if the other events will work when listeners are added later in the app startup.

I think this should probably be fixed better by the react-native-onesignal lib with an internal subscriber queue. I'll try to give it a shot, maybe do a pull-request in the near future for this scenario with delayed registration of event listeners.

All 25 comments

I am having some issues with onIds, which doesn't get called sometimes. However, this is not related to redux-persist.

It seems like the OneSignal servers are not reachable? However, the Doc says it should return null anyway. I am having this issue once every few tries, it's not consistent. I am not sure how reliable this event is now.

I was checking again on the simulator today and it took a good 10 seconds to get the "onIds" event, after having accepted the permissions through OneSignal.requestPermissions().

I have placed the same event in another place within the app to see if I still get the Ids, whenever I refresh (demo project behavior), but it doesn't work at all.

Further, it's not clear what the "registered" event should be about cause that's never triggered in any case.

Guys, the event never gets called when app is closed and opened again. I mean if the ids are available, shouldn't this get triggered every time?

The other issue is that it doesn't get triggered 1 out of 5 times (average), when the user accepts Push Notifications. This wouldn't be a problem if the first issue was okay, so we could pickup the id the next time the user opens the app.

I just started using this lib and hit the same issue. Using redux-persist here too! And after some digging, I strongly believe it has to do with redux-persist. Or any delayed subscription to the ids event.

The following code, if put right in the index.xxx.js (i.e. very early in the app start), it will trigger on every app restart:

//... other imports
import OneSignal from "react-native-onesignal";

OneSignal.addEventListener('ids', (device) => {
    console.log("[OneSignal]>>ids: ", device);
});

// ....

AppRegistry.registerComponent ....

However, if the OneSignal.addEventListener('ids' ... is called after redux-persist rehydration => kiss the callback goodbye.

FIX here's how I (hack?)fixed it, for now (current react-native-onesignal release 3.0.3):

there is an undocumented js-side method called OneSignal.configure() that makes the native side (android and ios) to broadcast the ids event back to the js-side.

So, call it right after adding the event listener for 'ids':

// ... after store rehydration complete ...

OneSignal.addEventListener('ids', (device) => {
   // ... do whatever with device
});

OneSignal.configure();  // add this to trigger `ids` event

By my assessment of how it's implemented in the native side and it seems to be pretty safe to call that, even more than one time (it just replaces the internal event handler, doesn't create more). But keep in mind, it fires the ids listeners each time.

I now wonder if the other events will work when listeners are added later in the app startup.

I think this should probably be fixed better by the react-native-onesignal lib with an internal subscriber queue. I'll try to give it a shot, maybe do a pull-request in the near future for this scenario with delayed registration of event listeners.

If you call OneSignal.configure(); before the event listener this works fine. I am not even sure if it's redux-persist.

Just a quick note I just had this issue with erratic behaviour with the onIds event not firing.

Now having added the configure function to another component which loads a little later in the app's launch i sometimes get a single onIds event firing and sometimes two (since the original one is firing on occasion still).

It's worth noting that I haven't tested this on release builds and am currently debugging on Android, React Native 0.38 and since others have suggested this is a redux persist issue its worth noting that I'm using that as well.

If there is indeed no negative affect to calling configure multiple times then i guess its fine. I'll just deal with it hitting my API twice each time a user resumes the application on occasion.

If there is some sort of negative result of doing this (other than inefficiency) please let me know as this isn't an area of expertise for me.

I have the same and we are in production. ;) Yes, I am calling the API twice. :(

Hi @edo1493 , I'm having the same issue as well. How do call the API twice?

I noticed that without reloading the app (Dev mode), the event will only fire after 35s

Edit:
This happens on first load of the app
Platform: Android

Maybe @jkasten2 will be able to help here, I think it's not a problem with this specific library,

@edo1493 onIds won't fire unless it can get a player / user id from the OneSignal server. This means that the userId will never be null however the pushToken may if APNs / FCM doesn't responded in time. The problem are seeing seems to be connection related. Can you try calling setLogLevel in native code to enable logging of network calls? If you are able to reproduce the issue with Android it will provide more details about calls being made in the logcat vs the Xcode log with iOS.

However most noted the issue seems to be related to redux-persist which would most likely mean an issue in the javascript layer with the OneSignal plugin. @avishayil Can you try reproducing the issue with redux-persist and try to pin point the issue? Share the project once you do I can try debugging it as well.

@jkasten2 I currently not using redux-persist in my projects so it would be hard to find the time to reproduce. I think it would be easier if one of the folks here will share a repo using redux-persist with the issue reproduced.

Not using redux and this is still an issue.

Thanks @rcugut ! OneSignal.configure() fix it immediately ! I'm using redux-persist too ! Need this to be fix !

Adding .configure fixed it for me as well, I'm not using react-persist.

For me OneSignal.configure() hack also works, but I noticed that OneSignal.removeEventListener("ids", this.onIds) is not working. Not sure if this is related. Any ideas how to fix this?

facing same thing as @junedomingo

In android, on first load of the app , ids event is called after 35 seconds

I don't have any problem on Android, the event fires up without any problem.
But I struggle on iOS, where I don't, never, come into the onIds() function...
Adding OneSignal.configure() before or after the event listeners and before or after the rehydratation was completed (yes, I'm using redux-persist) didn't helped.
Has anyone an idea?

@jkasten2 i have the same issue that @junedomingo mentioned here about on ids listener. i put log outside and inside this method

     OneSignal.idsAvailable(new OneSignal.IdsAvailableHandler() {
            public void idsAvailable(String userId, String registrationId) {
                final WritableMap params = Arguments.createMap();

                params.putString("userId", userId);
                params.putString("pushToken", registrationId);

                sendEvent("OneSignal-idsAvailable", params);
            }
        });

it responds after 30 seconds!
do you have any idea/solution?

if you have OneSignal.setRequiresUserPrivacyConsent(true);
it won't work untill you provide consent!
OneSignal.provideUserConsent(true);

also call OneSignal.configure() after add listeners.
Hope works for you!!!

Same problem
version: v3.3.1
Platform: iOS

As you can see here userId is null, its only after 29 seconds the event listener triggers with the userId. This is on first launch after clean install of the app.
Screen Shot 2019-08-05 at 3 04 59 PM

Anyone still with this problem?
The event is only triggered after ~30sec in the clear boot in android.

@damathryx Hi, I am facing the same userId null on first launch issue. Did you find a fix for it?

This issue should be reopened 😩

For me push notifications are not coming in on Android without .configure. Ids are triggered fine now, device info is received, but notifications themselves don't work.

Was this page helpful?
0 / 5 - 0 ratings