React Native: Null не является объектом - push-уведомление (OneSignal) - PullRequest
0 голосов
/ 21 января 2019

В данный момент я столкнулся с проблемой с моими push-уведомлениями .. Я пытаюсь запустить OneSignal в своем репо, и я следовал руководству по установке OneSignal и уже дважды проверил его. Все настроено правильно!

Однако у меня есть две проблемы, которые отличаются на iOS и Android. Существует три способа получения push-уведомления:

  • Случай 1: приложение открыто
  • Случай 2: приложение было открыто, закрыто (не убито) и все еще работает в фоновом режиме
  • Случай 3: приложение не открыто и не работает в фоновом режиме (было убито / убрано с экрана)

IOS: На моем iPhone чехол 1 и чехол 2 работают без проблем. Однако в случае 3 мое приложение показывает этот экран (изображения ниже).

Android: На телефонах Android случаи 1 и 3 работают без каких-либо проблем, но в случае 2 приложение не отображает мое всплывающее диалоговое окно .. Но также не вылетает и не работает!

Итак, я думаю, что, как показывает экран iOS, где-то есть проблема с моим состоянием, потому что это null. Тем не менее, на мой взгляд, все еще сбивает с толку, потому что именно этот случай работает в Android ...

Однако я использую функции и EventHandler, указанные в документации OneSignal. Кроме того, я использую библиотеку с именем react-native-popup-dialog для отображения всплывающего окна при отправке push-уведомления. Это всплывающее окно отображается только в том случае, если я отправляю определенные пары ключ / значение с push-уведомлением. Эти ключи:

  1. showPopup: true - Отображение всплывающего окна при значении true. Если он не установлен или не равен true, он не отображается!
  2. openLink: mydomain.de - добавляет кнопку со ссылкой на всплывающее окно
  3. buttonText: Open in Browser - Устанавливает текст кнопки для ссылки

Обратите внимание, что дополнительная кнопка URL добавляется во всплывающее окно только в том случае, если установлены ключи openLink и buttonText. Ни одна из них или только одна из клавиш не установлены, эта кнопка не отображается.

Пока все хорошо. Итак, вот мой исходный код, и я надеюсь, что вы, ребята, сможете мне помочь ... пытаясь отладить это за 3 дня ...

Обратите внимание, что метод getPopup () get вызывается несколькими (разными) экранами, расширяющими этот (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:

enter image description here enter image description here

1 Ответ

0 голосов
/ 21 января 2019

Проблема в том, что вы используете значение из состояния, которое не было установлено.Установка состояния является асинхронным действием, поэтому нет гарантии, что оно будет установлено к моменту его вызова.

Вы должны использовать объект уведомления напрямую, а не тот, который вы установили для состояния.

Подробнее о настройке состояния вы можете узнать здесь

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

...