Я думаю, у меня есть некоторые проблемы с состоянием моего приложения.Я уже понял, что this.setState({ ... })
- это функция, которая работает асинхронно. Итак, я думаю, что это как-то связано с моей проблемой.
Моя проблема в том, что я хочу показать всплывающее диалоговое окно моему пользователю, когда я отправляю push-уведомление через OneSignal.Это push-уведомление получает iOS и Android.Даже когда приложение работает в фоновом режиме, на переднем плане или было убито и даже не работает в фоновом режиме.Для всплывающего диалога я использую этот пакет: act-native-popup-dialog
Это всплывающее окно отображается только в том случае, если я отправляю определенные пары ключ / значение с push-уведомлением.Это следующие клавиши:
showPopup
: true
- Отображение всплывающего окна при значении true.Если он не установлен или не равен true, он не отображается! openLink
: mydomain.de
- добавляет кнопку со ссылкой на всплывающее окно buttonText
:Open in Browser
- Устанавливает текст кнопки для ссылки
Обратите внимание, что дополнительная кнопка URL добавляется только во всплывающее окно, если установлены ключи openLink
и buttonText
.Ни одна из них или только одна из клавиш не установлены, эта кнопка не отображается.
Однако всплывающее диалоговое окно иногда появляется только в некоторых случаях.Я перечислю их для вас ниже:
- Случай 1: Приложение открыто.В этом случае всплывающее окно появляется на iOS и Android.Это обрабатывается функцией
onReceived
! - Случай 2: Приложение полностью закрыто (убрано с экрана / убито).В этом случае всплывающее окно отображается на устройствах Android, но не на устройствах iOS!Это обрабатывается функцией
onOpened
! - Случай 3: приложение было открыто и теперь работает в фоновом режиме.В этом случае всплывающее окно отображается на устройствах iOS, но не на устройствах Android.Это также обрабатывается функцией
onOpened
!
Итак, поскольку я не получаю сообщения об ошибках или что-то еще, я предполагаю, что я прав, полагая, что эта проблема вызвана асинхронностью this.setState({ ... })
функция.
Теперь у меня вопрос: как я могу убедиться, что состояние notification
и visible
всегда устанавливается перед рендерингом метода getPopup(...)
? Я уже думал о его реализации, чтобы вызватьgetPopup(...)
функция с параметрами.Итак, я могу быть уверен, что параметры всегда устанавливаются перед вызовом метода.Однако, к сожалению, это невозможно.Потому что класс, который вы видите ниже, класс SuperScreen
, это просто класс, который расширяется некоторыми подклассами для связывания моего кода, такого как код push-уведомления или некоторые функции, которые мне нужны в каждом из этих подклассов.
ТакжеЯ уже пытался добавить переменную в мое состояние SuperClass
, например, с именем stateSet
, которая устанавливается после завершения функции setState({ ... })
onReceived
или onOpened
и проверить ее с помощью if(this.state.stateSet)
в первомстрока функции getPopup(...)
.Однако это также невозможно.Причина в том, что тогда мое всплывающее окно больше не закрывается, когда я нажимаю Ok
или кнопку ссылки.
Если у вас, ребята, есть какие-либо идеи о том, как решить эту проблему, я был бы очень признателен!Вот мой код:
export default class SuperScreen extends Component {
constructor(props) {
super(props);
this.state = {
pushNotification: null,
visible: false
};
OneSignal.init("00000000", {
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 => {
//App is opened!
console.log("Notification received: ", notification);
this.setState({
pushNotification: notification,
visible: true
});
if (notification.payload.notificationID != null) {
firebase.analytics().logEvent("Popup_Link_Button", {
notificationID: notification.payload.notificationID,
clicked: true
});
}
};
onOpened = openResult => {
//App either is closed or running in background
//Android: Closed: Showing Background: Not Showing
//iOS: Closed: Not Showing Background: Showing)
console.log("openResult: ", openResult);
this.setState({
pushNotification: openResult.notification,
visible: true
});
if (openResult.notification.payload.notificationID != null) {
firebase.analytics().logEvent("Popup_Link_Button", {
notificationID: openResult.notification.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 });
firebase.analytics().logEvent("Popup_Link_Button", {
popupID: this.state.pushNotification.payload.notificationID,
opened: false
});
}}
/>
];
}
return (
<Dialog
visible={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>
);
}
}