android - react native : Null is not an object - Push notification (OneSignal)

标签 android ios react-native state onesignal

目前我的推送通知遇到问题。我正在尝试在我的存储库中初始化 OneSignal,并且我已经按照 OneSignal 安装指南进行了双重检查。一切都设置正确!

但是,我遇到了两个在 iOS 和 Android 上不同的问题。可以通过三种方式接收推送通知:

  • 案例 1:打开应用
  • 案例2:应用已打开,已关闭(未被杀死)且仍在后台运行
  • 案例 3:应用未打开且未在后台运行(已被杀死/从屏幕上滑出)

苹果: 在我的 iPhone 上,手机壳 1 和手机壳 2 工作正常,没有任何问题。但是,在情况 3 中,我的应用程序显示此屏幕(下面附有图片)。

安卓: 在 Android 手机上,案例 1 和案例 3 没有任何问题,但在案例 2 中,应用程序没有显示我的弹出对话框。但也没有崩溃和运行!

所以,我认为,就像 iOS 屏幕告诉我的那样,我的状态存在某处问题,因为它是 null。然而,在我看来仍然令人困惑,因为这个案例在 Android 中确实有效......

但是,我使用的是 OneSignal 文档中提供的函数和 EventHandler。此外,我正在使用名为 react-native-popup-dialog 的库在发送推送通知时显示弹出窗口。仅当我通过推送通知发送某些键/值对时,此弹出窗 Eloquent 可见。这些键是:

  1. showPopup:true - 为 true 时显示弹出窗口。如果未设置或不等于 true,则不显示!
  2. openLink:mydomain.de- 添加一个带有弹出链接的按钮
  3. buttonText:在浏览器中打开 - 将按钮文本设置为链接

Note, the extra URL button is only added to the popup if key openLink and buttonText is set. Of none of them or only one of the key is set, it isn't displaying this button.

到目前为止一切顺利。所以,现在这是我的源代码,我希望你们能帮助我......从 3 天开始尝试调试......

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>
      );
    }
  }

我的 iPhone 图片:

enter image description here enter image description here

最佳答案

问题是您正在使用尚未设置的状态值。设置状态是一个异步操作,因此不能保证在您调用它时它会被设置。

您应该直接使用通知对象,而不是您设置状态的对象。

您可以在此处了解有关设置状态的更多信息

https://medium.learnreact.com/setstate-is-asynchronous-52ead919a3f0

这是我的意思的一个例子。

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
      });
    }
  };

您还需要更新 onOpened 函数

关于android - react native : Null is not an object - Push notification (OneSignal),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54297129/

相关文章:

python - 无法从 Android 上的 Kivy 应用程序发送蓝牙

java - 在Android中可以使用哪些编程语言进行开发?

ios - 通过 Swift 中一个键的多个值过滤 Firebase 结果

iOS 用户界面 : Need guidance to design such a flow of screens - which controllers should be best?

javascript - 如何使用 StackNavigator 将数据从一个屏幕内的列表传递到下一个屏幕

android - 将gridLayout的高度设置为wrap_content后 View 消失

android - 有人发现 SQLITE 'delete' 性能问题吗?

ios - 在 iOS 中将字符串拆分为子字符串

ios - React Native 版本 0.13.1 TabBar 图标不显示

javascript - 如何使用扩展语法返回对象并覆盖引用数组的属性