Reputation: 572
I am facing a problem with my push notifications at the moment.. I am trying to init OneSignal in my repo and I have followed the OneSignal installation guide and double checked it already. Everything is set up correctly!
However, I have two problems which are different on iOS and on Android. There are three ways to receive a push notification:
iOS: On my iPhone case 1 and case 2 are working perfectly without any issue. However, in case 3 my application is showing this screen (images attached below).
Android: On Android phones case 1 and 3 is working without any problems but in case 2 the app is not displaying my popup dialog.. But also is not crashing and running!
So, I think, like the iOS screen is telling me, there is somewhere a problem with my state cause it's null
. However, in my eyes is still confusing cause exactly this case is working in Android...
However, I am using the functions and EventHandler
given in the OneSignal documentation. Also, I am using a library called react-native-popup-dialog
to show a popup when sending a push notification. This popup is only visible if I send certain key/value pairs with the push notification. These keys are:
showPopup
:true
- Displaying the popup when true. If it isn't set or not equals true, it isn't displayed!openLink
:mydomain.de
- Adds a button with a link to the popupbuttonText
:Open in Browser
- Sets the button text to the link Note, the extra URL button is only added to the popup if key
openLink
andbuttonText
is set. Of none of them or only one of the key is set, it isn't displaying this button.
So far so good. So, here is my source code now and I hope you guys can help me out.. trying to debug this since 3 days...
Note, the method getPopup() get's called by several (different) screens which are extending this (SuperScreen) class.
import Dialog, { SlideAnimation, DialogTitle, DialogContent, DialogButton } from "react-native-popup-dialog";
import firebase from "react-native-firebase";
import OneSignal from "react-native-onesignal"
export default class SuperScreen extends Component {
constructor(props) {
super(props);
this.state = {
pushNotification: null,
visible: false
};
OneSignal.setLogLevel(6, 0);
OneSignal.init("00000000000000000000000000000000000", {
kOSSettingsKeyAutoPrompt: true
});
OneSignal.inFocusDisplaying(0);
OneSignal.enableVibrate(true);
OneSignal.enableSound(true);
OneSignal.addEventListener("received", this.onReceived);
OneSignal.addEventListener("opened", this.onOpened);
OneSignal.addEventListener("ids", this.onIds);
}
componentWillUnmount() {
OneSignal.removeEventListener("received", this.onReceived);
OneSignal.removeEventListener("opened", this.onOpened);
OneSignal.removeEventListener("ids", this.onIds);
}
onReceived = notification => {
console.log("Notification received: ", notification);
this.setState({
pushNotification: notification,
visible: true
});
if (this.state.pushNotification.payload.notificationID != null) {
firebase.analytics().logEvent("Popup_Link_Button", {
notificationID: this.state.pushNotification.payload.notificationID,
clicked: true
});
}
};
onOpened = openResult => {
console.log("Message: ", openResult.notification.payload.body);
console.log("Data: ", openResult.notification.payload.additionalData);
console.log("isActive: ", openResult.notification.isAppInFocus);
console.log("openResult: ", openResult);
this.setState({
pushNotification: openResult.notification,
visible: true
});
if (this.state.pushNotification.payload.notificationID != null) {
firebase.analytics().logEvent("Popup_Link_Button", {
notificationID: this.state.pushNotification.payload.notificationID,
clicked: true
});
}
};
onIds = device => {
console.log("Device info: ", device);
};
getPopup() {
if (
this.state.pushNotification != null &&
this.state.pushNotification.payload.additionalData != null &&
this.state.pushNotification.payload.additionalData.showPopup != null &&
this.state.pushNotification.payload.additionalData.showPopup == "true"
) {
var actionButtons = null;
if (
this.state.pushNotification.payload.additionalData.openLink != null &&
this.state.pushNotification.payload.additionalData.buttonText != null
) {
actionButtons = [
<DialogButton
text="Ok"
key={0}
onPress={() => {
this.setState({ visible: false });
firebase.analytics().logEvent("Popup_Link_Button", {
notificationID: this.state.pushNotification.payload
.notificationID,
opened: false
});
}}
/>
];
actionButtons.push(
<DialogButton
text={this.state.pushNotification.payload.additionalData.buttonText}
key={1}
onPress={() => {
this.openLink(
this.state.pushNotification.payload.additionalData.openLink
);
this.setState({ visible: false });
firebase.analytics().logEvent("Popup_Link_Button", {
notificationID: this.state.pushNotification.payload
.notificationID,
link: this.state.pushNotification.payload.additionalData
.openLink,
opened: true
});
}}
/>
);
} else {
actionButtons = [
<DialogButton
text="Ok"
key={0}
onPress={() => {
this.setState({ visible: false, pushNotification: null });
firebase.analytics().logEvent("Popup_Link_Button", {
popupID: this.state.pushNotification.payload.notificationID,
opened: false
});
}}
/>
];
}
return (
<Dialog
visible={this.state.visible == null ? false : this.state.visible}
dialogTitle={
<DialogTitle
title={
this.state.pushNotification == null
? ""
: this.state.pushNotification.payload.title
}
/>
}
dialogAnimation={
new SlideAnimation({
slideFrom: "bottom"
})
}
dialogStyle={{ marginLeft: 20, marginRight: 20 }}
actions={actionButtons}
>
<DialogContent>
<Text />
<Text>
{this.state.pushNotification == null
? ""
: this.state.pushNotification.payload.body}
</Text>
</DialogContent>
</Dialog>
);
}
}
My iPhone images:
Upvotes: 0
Views: 2195
Reputation: 28539
The problem is that you are using a value from state that hasn’t been set. Setting state is an asynchronous action so there is no guarantee that it will be set by the time you call it.
You should use the notification object directly and not the one you set to state.
You can learn more about setting state here
https://medium.learnreact.com/setstate-is-asynchronous-52ead919a3f0
Here is an example of what I am meaning.
onReceived = notification => {
console.log("Notification received: ", notification);
this.setState({
pushNotification: notification,
visible: true
});
// use the actual notification object instead of this.state.pushNotification.
if (notification.payload.notificationID != null) {
firebase.analytics().logEvent("Popup_Link_Button", {
notificationID: notification.payload.notificationID,
clicked: true
});
}
};
You will also need to update the onOpened function too
Upvotes: 1