【问题标题】:React Native: Null is not an object - Push notification (OneSignal)React Native:Null 不是对象 - 推送通知 (OneSignal)
【发布时间】:2019-01-21 20:11:10
【问题描述】:

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

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

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

iOS: 在我的 iPhone 案例 1 和案例 2 上运行良好,没有任何问题。但是,在案例 3 中,我的应用程序正在显示此屏幕(图片附在下面)。

安卓: 在 Android 手机上,案例 1 和 3 可以正常工作,但在案例 2 中,应用程序没有显示我的弹出对话框。但也没有崩溃和运行!

所以,我认为,就像 iOS 屏幕告诉我的那样,我的状态存在问题,因为它是 null。但是,在我看来仍然令人困惑,因为这种情况确实适用于 Android...

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

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

注意,额外的 URL 按钮仅在设置了键 openLinkbuttonText 时才会添加到弹出窗口中。其中没有一个或只设置了一个键,它不显示此按钮。

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

注意,getPopup() 方法被几个(不同的)屏幕调用,这些屏幕扩展了这个(SuperScreen)类。

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 图片:

【问题讨论】:

    标签: android ios react-native state onesignal


    【解决方案1】:

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

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

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

    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 函数

    【讨论】:

    • 但是,弹出窗口仍然没有出现在我的 iOS 设备上,但在我的 Android 设备上它是针对案例 3 的!
    • 当您在弹出窗口中使用状态时,可能存在另一种情况,即在设置状态之前调用它。也许将值作为参数传递给函数getPopUp 可能会解决这个问题。但是您还没有展示如何调用该函数。另一个选项可能是 iOS 没有收到通知中的值,你应该检查这些。
    • 我无法将它们直接传递给函数,因为它们是从扩展此类的子类中调用的。但是,正如您在getPopup() 的第一行中看到的那样 -> 我正在使用 if 语句检查状态。此外,当状态更新时,弹出窗口应该总是更新(所以,之后 - 不应该有问题)!
    • 但是 setState 是异步的,所以在调用 getPopUp 时它可能还没有完成设置。这意味着this.state.visible 可能仍然是错误的,这意味着它不会显示弹出窗口
    • 但是getPopup(..)在启动应用程序时总是不可见的。它仅在发送和接收推送通知后设置为可见,并且我已将状态设置为可见并设置 pushNotification 的状态。所以它基本上是在渲染自己!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    • 2022-06-28
    • 2015-12-19
    • 2021-09-28
    • 1970-01-01
    • 2021-11-11
    • 2016-11-12
    相关资源
    最近更新 更多