React-native-onesignal: addSubscriptionObserver and getDeviceState both are gives null push token and user id while open app.

Created on 5 Nov 2020  路  18Comments  路  Source: OneSignal/react-native-onesignal

for addSubscriptionObserver : {
"to": {
"isSubscribed": false,
"isPushDisabled": false
},
"from": {
"isSubscribed": false,
"isPushDisabled": true
}
}

For getDeviceState : {
"isEmailSubscribed": false,
"isSubscribed": false,
"isPushDisabled": false,
"hasNotificationPermission": true
}

I'm using following version of onesignal.
react-native-onesignal: ^4.0.0-beta.2

Possible Bug

Most helpful comment

class NotificationListner extends React.Component {
state = {
push_token: null,
push_user_id: null
};

constructor(properties) {
    super(properties);
    OneSignal.setAppId(KEY_CONSTANT.ONE_SIGNAL_APP_ID);
}
componentWillMount() {
    if (Platform.OS == 'ios') {
        OneSignal.promptForPushNotificationsWithUserResponse(myiOSPromptCallback);
    }
    OneSignal.setNotificationWillShowInForegroundHandler(notifReceivedEvent => {
        print_data('============notification will show==============' + JSON.stringify(notifReceivedEvent, null, 2))
    });
    OneSignal.setNotificationOpenedHandler(openedEvent => {
        print_data('============notification will open==============' + JSON.stringify(openedEvent, null, 2))
    });

    OneSignal.addSubscriptionObserver(event => {
        print_data('============on subscription change in listner==============' + JSON.stringify(event, null, 2))
    });
    this.get_token()
}

componentWillUnmount() {  
    OneSignal.clearHandlers();
    }

async get_token() {
    const deviceState = await OneSignal.getDeviceState();
    print_data('============on device state is in listner==============' + JSON.stringify(deviceState, null, 2))
    }
}
render() {
    return (
        <View style={{ width: 100, height: 100 }}></View>
    );
}

}
export default NotificationListner;

==================================

My App.js contain following codes.

==================================

export default class App extends React.Component {

constructor(props) {
super(props)
}
render() {
console.disableYellowBox = true;
return (

);
}

}

All 18 comments

Howdy,
Please follow our issue template guide so that we can better assist you. Please include the actual code snippet you are calling that is printing this.

Cheers

OneSignal.addSubscriptionObserver(event => {
print_data('============on subscription change in listner==============' + JSON.stringify(event, null, 2))

    });

Data getting from above code is : {
"to": {
"isSubscribed": false,
"isPushDisabled": false
},
"from": {
"isSubscribed": false,
"isPushDisabled": true
}
}

=============

const deviceState = await OneSignal.getDeviceState();

Data getting from above code is : {
"isEmailSubscribed": false,
"isSubscribed": false,
"isPushDisabled": false,
"hasNotificationPermission": true
}

You left off your initialization. Can you please include your entire OneSignal code?

class NotificationListner extends React.Component {
state = {
push_token: null,
push_user_id: null
};

constructor(properties) {
    super(properties);
    OneSignal.setAppId(KEY_CONSTANT.ONE_SIGNAL_APP_ID);
}
componentWillMount() {
    if (Platform.OS == 'ios') {
        OneSignal.promptForPushNotificationsWithUserResponse(myiOSPromptCallback);
    }
    OneSignal.setNotificationWillShowInForegroundHandler(notifReceivedEvent => {
        print_data('============notification will show==============' + JSON.stringify(notifReceivedEvent, null, 2))
    });
    OneSignal.setNotificationOpenedHandler(openedEvent => {
        print_data('============notification will open==============' + JSON.stringify(openedEvent, null, 2))
    });

    OneSignal.addSubscriptionObserver(event => {
        print_data('============on subscription change in listner==============' + JSON.stringify(event, null, 2))
    });
    this.get_token()
}

componentWillUnmount() {  
    OneSignal.clearHandlers();
    }

async get_token() {
    const deviceState = await OneSignal.getDeviceState();
    print_data('============on device state is in listner==============' + JSON.stringify(deviceState, null, 2))
    }
}
render() {
    return (
        <View style={{ width: 100, height: 100 }}></View>
    );
}

}
export default NotificationListner;

==================================

My App.js contain following codes.

==================================

export default class App extends React.Component {

constructor(props) {
super(props)
}
render() {
console.disableYellowBox = true;
return (

);
}

}

I have the same issue. I followed the instructions from the one signal documentation.

"react-native-onesignal": "^4.0.3",
"react-native": "^0.63.3",

`
OneSignal.setAppId('0b3c99cc-4683-498b-bfb9-8b2b1760af71');
OneSignal.setLogLevel(6, 0);
OneSignal.setRequiresUserPrivacyConsent(true);
OneSignal.promptForPushNotificationsWithUserResponse((response) => {
console.log('Prompt response:', response);
});

/* O N E S I G N A L  H A N D L E R S */
OneSignal.setNotificationWillShowInForegroundHandler(
  (notifReceivedEvent) => {
    console.log(
      'OneSignal: notification will show in foreground:',
      notifReceivedEvent,
    );
    let notif = notifReceivedEvent.getNotification();
  },
);
OneSignal.setNotificationOpenedHandler((notification) => {
  console.log('OneSignal: notification opened:', notification);
});
OneSignal.setInAppMessageClickHandler((event) => {
  console.log('OneSignal IAM clicked:', event);
});
OneSignal.addEmailSubscriptionObserver((event) => {
  console.log('OneSignal: email subscription changed: ', event);
});
OneSignal.addSubscriptionObserver((event) => {
  console.log('OneSignal: subscription changed:', event);
  setIsSubscribed(event.to.isSubscribed);
});
OneSignal.addPermissionObserver((event) => {
  console.log('OneSignal: permission changed:', event);
});

const deviceState = await OneSignal.getDeviceState();
setIsSubscribed(deviceState.isSubscribed);

updateOneSignalToken({
  token: deviceState.pushToken,
  deviceId: deviceState.userId,
});
console.log('-> deviceState', deviceState);

`

I have the same problem

Did you get the solution?

Same here.

Howdy y'all,
What platform is this occurring on?

Note: Please refer to our documentation. This function returns a "snapshot" so if you are calling it before OneSignal has had the time to initialize and subscribe, it will not return the value you are looking for. (Do not cache)

The subscription observer callback parameter also has pushToken so consider using that one instead. I do see reports above that this one doesn't work either. Can you please provide logs?

Does push work at all? (ie: is this a reporting issue or is the player never being successfuly subscribed?)

I had to use addSubscriptionObserver and store it in the async 2nd time. 1st time the getDeviceState was not giving it to store it. so, used addSubscriptionObserver and stored.

yes i'm added timeout interval to get device state after every 1 minute and once get both token and user id i'm clearing these timeout..It is worked for me.

this.timer = setInterval(async () => {

                this.get_device_state()

        }, 60000);

async get_device_state() {
const deviceState = await OneSignal.getDeviceState();
}

Sim, adicionei o intervalo de tempo limite para obter o estado do dispositivo a cada 1 minuto e, uma vez que obtiver o token e a ID do usu谩rio, estou limpando esse tempo limite ... Funcionou para mim.

this.timer = setInterval (async () => {

                this.get_device_state()

        }, 60000);

async get_device_state () {
const deviceState = await OneSignal.getDeviceState ();
}

it didn't help me, I'm lost

Howdy,
Which platform are you reproducing this issue on? Android or iOS?

I had to upgrade to a newer native version, after that I downloaded the TS example and converted it to JS (because my project is without TS) and used OsLog to record the player_id just so I finally had peace.

    async OSLog(message, optionalArg) {

        if (optionalArg) {
            message = message + JSON.stringify(optionalArg);
        }

        if (optionalArg['to'] && optionalArg['to']['userId']) {
            console.log(optionalArg['to']['userId']);
        }
             ....
    }

as the topic was created precisely because they are also unable to use the
add Subscription Observer
what @sanjeevkse Sanjeevkse may not be the solution, but what is viable before solving the problem as a whole, is to update the react native, test the Subscription exactly like @sanjeevkse and if it doesn't work, resort to what I did. I tested in Xaiomi and Sansung. everything is OK

yes i'm added timeout interval to get device state after every 1 minute and once get both token and user id i'm clearing these timeout..It is worked for me.

this.timer = setInterval(async () => {

                this.get_device_state()

        }, 60000);

async get_device_state() {
const deviceState = await OneSignal.getDeviceState();
}

Solution by @krupalikevadiya saved me! But instead of using setInterval, I am using setTimeout so that it will trigger the getDeviceStated() only once. Here's my code for that part:

setTimeout(async () => {
   const deviceState = await OneSignal.getDeviceState();
   let userId = deviceState.userId;
   console.log(userId);
}, 8000);

I have tried trigger the getDeviceStated() after less than 8 seconds but it will return the value of undefined userId. So 8 seconds and above should be no problem. Tested and proven.

Sim, adicionei o intervalo de tempo limite para obter o estado do dispositivo a cada 1 minuto e, uma vez que obtiver o token e a ID do usu谩rio, estou limpando esse tempo limite. Funcionou para mim.
this.timer = setInterval (async () => {

                this.get_device_state()

        }, 60000);

async get_device_state () {
const deviceState = await OneSignal.getDeviceState ();
}

A solu莽茫o de @krupalikevadiya me salvou! Mas em vez de usar setInterval, estou usando setTimeoutpara que seja acionado getDeviceStated()apenas uma vez. Este 茅 meu c贸digo para essa parte:

setTimeout(async () => {
   const deviceState = await OneSignal.getDeviceState();
   let userId = deviceState.userId;
   console.log(userId);
}, 8000);

Tentei acionar o getDeviceStated()depois de menos de 8 segundos, mas ele retornar谩 o valor de undefineduserId. Portanto, 8 segundos ou mais n茫o devem ser problema. Testado e comprovado.

if you take the project example in RN copy the OSLog and put it in your project you can place a conditional as I did in the comment above, it is much more guaranteed. remember that each device behaves in a hardware dependent manner (processing), its 8 seconds may not work.

Howdy,
This might be related to https://github.com/OneSignal/react-native-onesignal/issues/1159

Instead of delaying the device state getter via a timer, try putting the getDeviceState function call in the subscription observer. This way, you will know that it is subscribed. e.g:

OneSignal.addSubscriptionObserver(async (event) => {
    this.OSLog("OneSignal: subscription changed:", event);
    if (event.to.isSubscribed) {
        const state = await OneSignal.getDeviceState();
        // do something with the device state
    }
});

Closing due to inactivity

Was this page helpful?
0 / 5 - 0 ratings