React-native-onesignal: كيف أحصل على الإخطار الأولي؟

تم إنشاؤها على ٢ أكتوبر ٢٠١٧  ·  22تعليقات  ·  مصدر: OneSignal/react-native-onesignal

تحتوي الوحدة النمطية React Native PushNotificationIOS على طريقة getInitialNotification() تسمح بجلب الإخطار الذي تم النقر عليه لفتح التطبيق (إذا كان هناك واحد). هل هناك بعض الوظائف المماثلة لهذه المكتبة؟

عندما أرسلت إخطار اختبار إلى جهازي أثناء إغلاق التطبيق ، تلقيت سجل Device info: في وحدة التحكم الخاصة بي عند فتحها ، لكنني لم أر أيًا من سجلات الأحداث الأخرى لتلقي إشعار.

تحرير 3:
لسبب ما ، لم أعد قادرًا على رؤية حدث onOpened للإشعارات الأولية ، على الرغم من عدم تغيير أي شيء في الكود الخاص بي.

تحرير 2:
من خلال التنقل بين المستمعين ، تمكنت من رؤية سجل الحدث onOpened ، لكن كونك مستمعًا سلبيًا يعني أنه لا يمكنني التحقق بشكل نشط لمعرفة ما إذا كان تطبيقي قد تم فتحه بإشعار أم لا ، علي فقط أن أنتظر بعض الوقت التعسفي لمعرفة ما إذا كان هذا الحدث قد تم إطلاقه؟ هل لا توجد طريقة للتحقق بفعالية مما إذا كان التطبيق قد تم فتحه بإشعار دفع أم لا؟

تعديل:
لقد عثرت على مقال يشير إلى استخدام OneSignal.configure() و onNotificationOpened ، لكن بالنظر إلى الكود المصدري ، لا يبدو أن OneSignal.configure() يقبل المعلمات بعد الآن؟

Documentation

التعليق الأكثر فائدة

لدي نفس المشكلة ، ويبدو أن العديد من الآخرين يواجهون هذه المشكلة أيضًا. تتضمن بعض المشكلات ذات الصلة / المكررة التي وجدتها https://github.com/geektimecoil/react-native-onesignal/issues/206 ، https://github.com/geektimecoil/react-native-onesignal/issues/195 ، https://github.com/geektimecoil/react-native-onesignal/issues/191 ، https://github.com/geektimecoil/react-native-onesignal/issues/336 ، https://github.com/geektimecoil/ رد فعل - أصلية - إشارات / قضايا / 334 ، https://github.com/geektimecoil/react-native-onesignal/issues/264 ، https://github.com/geektimecoil/react-native-onesignal/issues/279.

يبدو أن جميع هذه المشكلات تتعلق بمشكلة مستمع الحدث opened الذي لم يتم الاتصال به عند النقر فوق إشعار الدفع لفتح التطبيق والتطبيق لا يعمل في ذلك الوقت. من خلال ما قرأته في هذه المشكلات والاختبار الذي قمت به ، يبدو أن سبب هذه المشكلة هو تأخير تسجيل مستمع الحدث بأي شكل من الأشكال (على سبيل المثال ، يتم استدعاء OneSignal.addEventListener('opened', this.onOpened); قليلاً بعد تم تحميل التطبيق نفسه). قد يكون هذا بسبب وجود هذا الرمز داخل مكون React (على سبيل المثال في الدالات constructor أو componentWillMount أو componentDidMount ) ، أو لأنه لم يتم استدعاؤه إلا بعد التهيئة / إعادة الترطيب متجر Redux الخاص بك ، وما إلى ذلك. وبسبب هذا التأخير ، يتم تشغيل الحدث نفسه (الذي تم فتح إشعار به) بواسطة رد فعل - أصلي - إشارة واحدة قبل تسجيل مستمع الحدث ، وفي هذه المرحلة فاتتك الحدث ولديك لا توجد طريقة لمعرفة ما حدث. كملاحظة جانبية ، تؤثر هذه المشكلة نفسها على مستمعي الأحداث الآخرين ، على سبيل المثال ، مستمع الحدث ids .

إذا قمت بنقل هذا الرمز بحيث يحدث في أقرب وقت ممكن ، فيبدو أنه سيتم تسجيل مستمع الحدث قبل إطلاق الحدث وبالتالي سيتم استدعاء وظيفة معالج الحدث. على سبيل المثال ، يجب عليك نقل رمز تسجيل مستمع الحدث إلى ملف index.ios.js ، أو في بداية ملف App.js في حالة استيراد ملف index.ios.js فقط المكون App وتسجيله (عبر AppRegistry.registerComponent ).

بمجرد الانتهاء من هذا الإعداد ، يمكنك الآن التقاط الحدث الذي تم فيه فتح إشعار ويعود الأمر إليك في كيفية التعامل معه ، والذي سيعتمد على كيفية إعداد تطبيقك (على سبيل المثال ، ما إذا كنت تستخدم Redux ، أو ما إذا كنت تستخدم redux-persist ، وما إلى ذلك).

الحل الحالي الخاص بي هو حفظ الإشعار إلى متغير محدد في المستوى الأعلى لملف App.js الخاص بي نفسه (قبل أن أعلن حتى عن مكون App الخاص بي) ، ثم بمجرد الانتهاء من تهيئة متجر Redux الخاص بي (والذي يتضمن انتظار إعادة تميؤ متجري بواسطة redux-persist) ، أرسل الإجراءات مع الإشعار كحمولة (إذا كان هناك إشعار مفتوح) ، ثم أزيل أيضًا مستمعي الأحداث عالية المستوى وأضيف حدثًا جديدًا المستمعين على مكون App الخاص بي نفسه (يقوم مستمعو الأحداث هؤلاء أيضًا بإرسال الإجراءات إلى متجر Redux الخاص بي مع الإشعار ومعرفات الجهاز وما إلى ذلك كحمل الإجراء).

من الواضح أن هذا الحل متطفل للغاية ، ومن المحتمل أن تكون هناك بعض الحالات المتطورة حيث لن يعمل هذا كما يفترض. ولكن حتى يتم تنفيذ حل مناسب في رد فعل - أصلي - إشارة واحدة ، يبدو أن هذا حل مناسب.

أعتقد أن ما يجب أن يحدث هو تحديث إشارات رد الفعل الأصلية بحيث تنتظر حتى تقوم بإعداد معالجات الأحداث الخاصة بك قبل أن تنطلق الأحداث. قد يكون أحد الحلول الممكنة هو أنه عند وقوع الأحداث (مثل الحدث opened ) ، يتم وضع الأحداث في قائمة انتظار ، ثم يتم التحقق من وجود مستمع مناسب مسجل حاليًا. إذا لم يكن هناك ، فإنه يترك الحدث في قائمة الانتظار. بعد ذلك ، بمجرد تسجيل مستمع الحدث ، يتم تشغيل الأحداث التي سيستقبلها مستمع الحدث هذا وإزالتها من قائمة الانتظار. بهذه الطريقة ، يمكنك إضافة مستمعين للأحداث في التطبيق في أي وقت (على سبيل المثال ، بعد انتظار تهيئة متجر Redux الخاص بك وإعادة ترطيبه ، والذي من المحتمل أن يكون بعد 1-2 ثانية من تحميل التطبيق نفسه) ، وبعد ذلك في أقرب وقت تم تسجيل مستمعي الحدث ، سيتم استدعاء وظائف معالج الحدث الخاص بك واستلام الأحداث التي حدثت (مثل الحدث الذي تم فيه فتح إعلام).

هناك حل آخر محتمل ، على الأقل لاكتشاف أن التطبيق قد تم فتحه على وجه التحديد لأن المستخدم نقر على إشعار الدفع ، وهو القيام بشيء مشابه لـ getInitialNotification() من PushNotificationIOS كما اقترحت ، حيث يمكنك استدعاء هذه الوظيفة في أي وقت وستقوم بإرجاع إشعار الدفع الذي نقر المستخدم عليه لفتح التطبيق (أو null إذا لم يحدث ذلك). ولكن حتى إذا تم تنفيذ هذا في رد فعل-أصلي-إشارة واحدة ، فلن يفعل أي شيء لحل هذه المشكلة التي تؤثر على مستمعي الأحداث الآخرين (على سبيل المثال ، مستمع الحدث ids ).

لذلك أعتقد أن هناك حقًا بحاجة إلى حل يعالج هذه المشكلة الأساسية للأحداث التي يتم إطلاقها قبل تسجيل أي مستمع مناسب للأحداث ، مما يؤدي إلى تفويت الحدث من قبل التطبيق.

ال 22 كومينتر

لدي نفس المشكلة ، ويبدو أن العديد من الآخرين يواجهون هذه المشكلة أيضًا. تتضمن بعض المشكلات ذات الصلة / المكررة التي وجدتها https://github.com/geektimecoil/react-native-onesignal/issues/206 ، https://github.com/geektimecoil/react-native-onesignal/issues/195 ، https://github.com/geektimecoil/react-native-onesignal/issues/191 ، https://github.com/geektimecoil/react-native-onesignal/issues/336 ، https://github.com/geektimecoil/ رد فعل - أصلية - إشارات / قضايا / 334 ، https://github.com/geektimecoil/react-native-onesignal/issues/264 ، https://github.com/geektimecoil/react-native-onesignal/issues/279.

يبدو أن جميع هذه المشكلات تتعلق بمشكلة مستمع الحدث opened الذي لم يتم الاتصال به عند النقر فوق إشعار الدفع لفتح التطبيق والتطبيق لا يعمل في ذلك الوقت. من خلال ما قرأته في هذه المشكلات والاختبار الذي قمت به ، يبدو أن سبب هذه المشكلة هو تأخير تسجيل مستمع الحدث بأي شكل من الأشكال (على سبيل المثال ، يتم استدعاء OneSignal.addEventListener('opened', this.onOpened); قليلاً بعد تم تحميل التطبيق نفسه). قد يكون هذا بسبب وجود هذا الرمز داخل مكون React (على سبيل المثال في الدالات constructor أو componentWillMount أو componentDidMount ) ، أو لأنه لم يتم استدعاؤه إلا بعد التهيئة / إعادة الترطيب متجر Redux الخاص بك ، وما إلى ذلك. وبسبب هذا التأخير ، يتم تشغيل الحدث نفسه (الذي تم فتح إشعار به) بواسطة رد فعل - أصلي - إشارة واحدة قبل تسجيل مستمع الحدث ، وفي هذه المرحلة فاتتك الحدث ولديك لا توجد طريقة لمعرفة ما حدث. كملاحظة جانبية ، تؤثر هذه المشكلة نفسها على مستمعي الأحداث الآخرين ، على سبيل المثال ، مستمع الحدث ids .

إذا قمت بنقل هذا الرمز بحيث يحدث في أقرب وقت ممكن ، فيبدو أنه سيتم تسجيل مستمع الحدث قبل إطلاق الحدث وبالتالي سيتم استدعاء وظيفة معالج الحدث. على سبيل المثال ، يجب عليك نقل رمز تسجيل مستمع الحدث إلى ملف index.ios.js ، أو في بداية ملف App.js في حالة استيراد ملف index.ios.js فقط المكون App وتسجيله (عبر AppRegistry.registerComponent ).

بمجرد الانتهاء من هذا الإعداد ، يمكنك الآن التقاط الحدث الذي تم فيه فتح إشعار ويعود الأمر إليك في كيفية التعامل معه ، والذي سيعتمد على كيفية إعداد تطبيقك (على سبيل المثال ، ما إذا كنت تستخدم Redux ، أو ما إذا كنت تستخدم redux-persist ، وما إلى ذلك).

الحل الحالي الخاص بي هو حفظ الإشعار إلى متغير محدد في المستوى الأعلى لملف App.js الخاص بي نفسه (قبل أن أعلن حتى عن مكون App الخاص بي) ، ثم بمجرد الانتهاء من تهيئة متجر Redux الخاص بي (والذي يتضمن انتظار إعادة تميؤ متجري بواسطة redux-persist) ، أرسل الإجراءات مع الإشعار كحمولة (إذا كان هناك إشعار مفتوح) ، ثم أزيل أيضًا مستمعي الأحداث عالية المستوى وأضيف حدثًا جديدًا المستمعين على مكون App الخاص بي نفسه (يقوم مستمعو الأحداث هؤلاء أيضًا بإرسال الإجراءات إلى متجر Redux الخاص بي مع الإشعار ومعرفات الجهاز وما إلى ذلك كحمل الإجراء).

من الواضح أن هذا الحل متطفل للغاية ، ومن المحتمل أن تكون هناك بعض الحالات المتطورة حيث لن يعمل هذا كما يفترض. ولكن حتى يتم تنفيذ حل مناسب في رد فعل - أصلي - إشارة واحدة ، يبدو أن هذا حل مناسب.

أعتقد أن ما يجب أن يحدث هو تحديث إشارات رد الفعل الأصلية بحيث تنتظر حتى تقوم بإعداد معالجات الأحداث الخاصة بك قبل أن تنطلق الأحداث. قد يكون أحد الحلول الممكنة هو أنه عند وقوع الأحداث (مثل الحدث opened ) ، يتم وضع الأحداث في قائمة انتظار ، ثم يتم التحقق من وجود مستمع مناسب مسجل حاليًا. إذا لم يكن هناك ، فإنه يترك الحدث في قائمة الانتظار. بعد ذلك ، بمجرد تسجيل مستمع الحدث ، يتم تشغيل الأحداث التي سيستقبلها مستمع الحدث هذا وإزالتها من قائمة الانتظار. بهذه الطريقة ، يمكنك إضافة مستمعين للأحداث في التطبيق في أي وقت (على سبيل المثال ، بعد انتظار تهيئة متجر Redux الخاص بك وإعادة ترطيبه ، والذي من المحتمل أن يكون بعد 1-2 ثانية من تحميل التطبيق نفسه) ، وبعد ذلك في أقرب وقت تم تسجيل مستمعي الحدث ، سيتم استدعاء وظائف معالج الحدث الخاص بك واستلام الأحداث التي حدثت (مثل الحدث الذي تم فيه فتح إعلام).

هناك حل آخر محتمل ، على الأقل لاكتشاف أن التطبيق قد تم فتحه على وجه التحديد لأن المستخدم نقر على إشعار الدفع ، وهو القيام بشيء مشابه لـ getInitialNotification() من PushNotificationIOS كما اقترحت ، حيث يمكنك استدعاء هذه الوظيفة في أي وقت وستقوم بإرجاع إشعار الدفع الذي نقر المستخدم عليه لفتح التطبيق (أو null إذا لم يحدث ذلك). ولكن حتى إذا تم تنفيذ هذا في رد فعل-أصلي-إشارة واحدة ، فلن يفعل أي شيء لحل هذه المشكلة التي تؤثر على مستمعي الأحداث الآخرين (على سبيل المثال ، مستمع الحدث ids ).

لذلك أعتقد أن هناك حقًا بحاجة إلى حل يعالج هذه المشكلة الأساسية للأحداث التي يتم إطلاقها قبل تسجيل أي مستمع مناسب للأحداث ، مما يؤدي إلى تفويت الحدث من قبل التطبيق.

مرحبًا jordanmkoncz ، هل يمكنك مشاركة رمز الملف الذي أرسلت إليه الإجراءات؟ لدي نفس إعداد التفاعل الأصلي مثلك (إعادة الظهور وما إلى ذلك ..)

ccoeder بالتأكيد ، هذا هو ملفي الحالي App.js .

import React, { Component } from 'react';
import { Provider } from 'react-redux';
import OneSignal from 'react-native-onesignal';
import isNil from 'lodash/isNil';
import configureStore from '../redux/configureStore';
import {
  pushNotificationIdsReceived,
  pushNotificationOpened,
  pushNotificationReceived,
  pushNotificationRegistered,
} from '../redux/actionCreators';
import AppNavigator from './AppNavigator';
import Blank from './Blank';

let openedPushNotificationResult = null;
let receivedPushNotification = null;
let receivedNotificationUserInfo = null;
let receivedIds = null;

const onOpened = openResult => {
  openedPushNotificationResult = openResult;
};

const onReceived = notification => {
  receivedPushNotification = notification;
};

const onRegistered = notificationUserInfo => {
  receivedNotificationUserInfo = notificationUserInfo;
};

const onIds = ids => {
  receivedIds = ids;
};

OneSignal.addEventListener('opened', onOpened);
OneSignal.addEventListener('received', onReceived);
OneSignal.addEventListener('registered', onRegistered);
OneSignal.addEventListener('ids', onIds);

class App extends Component {
  constructor() {
    super();

    this.state = {
      isStoreInitialised: false,
    };

    this.store = null;

    this.onOpened = this.onOpened.bind(this);
    this.onReceived = this.onReceived.bind(this);
    this.onRegistered = this.onRegistered.bind(this);
    this.onIds = this.onIds.bind(this);
  }

  componentDidMount() {
    this.store = configureStore(store => {
      if (!isNil(openedPushNotificationResult)) {
        store.dispatch(pushNotificationOpened(openedPushNotificationResult));
      }

      if (!isNil(receivedPushNotification)) {
        store.dispatch(pushNotificationReceived(receivedPushNotification));
      }

      if (!isNil(receivedNotificationUserInfo)) {
        store.dispatch(pushNotificationRegistered(receivedNotificationUserInfo));
      }

      if (!isNil(receivedIds)) {
        store.dispatch(pushNotificationIdsReceived(receivedIds));
      }

      OneSignal.addEventListener('opened', this.onOpened);
      OneSignal.addEventListener('received', this.onReceived);
      OneSignal.addEventListener('registered', this.onRegistered);
      OneSignal.addEventListener('ids', this.onIds);

      OneSignal.removeEventListener('opened', onOpened);
      OneSignal.removeEventListener('received', onReceived);
      OneSignal.removeEventListener('registered', onRegistered);
      OneSignal.removeEventListener('ids', onIds);

      this.setState({ isStoreInitialised: true });
    });
  }

  componentWillUnmount() {
    OneSignal.removeEventListener('opened', this.onOpened);
    OneSignal.removeEventListener('received', this.onReceived);
    OneSignal.removeEventListener('registered', this.onRegistered);
    OneSignal.removeEventListener('ids', this.onIds);
    OneSignal.removeEventListener('opened', onOpened);
    OneSignal.removeEventListener('received', onReceived);
    OneSignal.removeEventListener('registered', onRegistered);
    OneSignal.removeEventListener('ids', onIds);
  }

  onOpened(openResult) {
    this.store.dispatch(pushNotificationOpened(openResult));
  }

  onReceived(notification) {
    this.store.dispatch(pushNotificationReceived(notification));
  }

  onRegistered(notificationUserInfo) {
    this.store.dispatch(pushNotificationRegistered(notificationUserInfo));
  }

  onIds(ids) {
    this.store.dispatch(pushNotificationIdsReceived(ids));
  }

  render() {
    if (!this.state.isStoreInitialised) {
      return <Blank />;
    }

    return (
      <Provider store={this.store}>
        <AppNavigator />
      </Provider>
    );
  }
}

export default App;

ملاحظة: configureStore هي وظيفة تنشئ متجر Redux الخاص بي (أي تستدعي createStore() ) ، ثم تقوم بإعداد redux-persist (أي تستدعي persistStore() ). يأخذ configureStore وظيفة رد الاتصال كمعامل ، وفي رد الاتصال onComplete # $ 6 $ # $ لوظيفة persistStore أستدعى وظيفة رد الاتصال التي تم تمريرها إلى configureStore وتمرير المتجر الكائن كمعامل لهذا الاستدعاء. أخيرًا ، يُرجع configureStore كائن المتجر.

لذلك ، في الأساس ، أنتظر حتى يتم إعداد متجري وإعادة ترطيبه ، ثم أرسل الإجراءات بناءً على الأحداث التي يتلقاها المستمعون الأوليون للحدث ، ثم أضف مستمعي الحدث الجدد وأزل مستمعي الحدث الأولي.

jordanmkoncz شكرا لتقاسم الكود الخاص بك. في البداية اعتقدت أن لدي نفس الخطأ الذي تعرضت له ، لكنني أدركت أن مشكلتي تتعلق بالإخطار الصامت. أحتاج إلى اتخاذ إجراء إذا جاء الإشعار أثناء إغلاق التطبيق. أعتقد أن الرموز الخاصة بك لا تعمل من أجلي.

لا تقلقccoeder. نعم ، مسألة اتخاذ إجراء فعليًا بشأن إشعار أثناء إغلاق التطبيق مشكلة مختلفة. تتعلق هذه المشكلة تحديدًا باكتشاف التطبيق أن المستخدم نقر على إشعار لفتح التطبيق ، في وقت تشغيل التطبيق (عندما لم يكن قيد التشغيل من قبل على الإطلاق).

ألقِ نظرة على كيفية عمل رد فعل الأم ، فهناك طريقة تسمى getInitialNotification

jordanmkoncz شكرا للنشر الخاص بك.

لدي مشكلة مماثلة. عندما يتلقى التطبيق إشعار الدفع ، تنتقل الشاشة إلى الشاشة المطلوبة.
ولكن عند فتح الإشعار ، فإنه لا يعمل مع وظيفة دفع التنقل.
مثال:
componentWillMount () {
OneSignal.addEventListener ("تم الاستلام" ، هذا _ عند الاستلام) ؛
OneSignal.addEventListener ('مفتوح' ، هذا ._ عند الفتح) ؛
}
componentWillUnmount () {
OneSignal.removeEventListener ("تم الاستلام" ، هذا ___ عند الاستلام) ؛
OneSignal.removeEventListener ('مفتوح' ، هذا ._ عند الفتح) ؛
}
_onRecevied (إعلام) {
console.log ('تم استلام الإشعار:' ، إعلام) ؛ // يعمل بشكل جيد
this.props.navigator.push ({pushSreen، passProps: {params}})؛ // يعمل بشكل جيد
}
_onOpened (openResult) {
console.log ('Notification body:'، openResult.notification.payload.body) ؛ // يعمل بشكل جيد
this.props.navigator.push ({pushSreen، passProps: {params}})؛ // لا يعمل
}

ما رأيك بهذا؟ إذا كنت تستطيع مساعدتي ، آمل أن أرجو الرد هنا. شكرا

حسنًا .. لدي مكوِّن PushNotificationHelper كطفل من Redux Provider ، والذي يتم تقديمه فقط بعد إعادة ترطيب store .

componentWillMount() {
    AppState.addEventListener("change", this.handleAppStateChange);
    OneSignal.configure({
      onNotificationOpened: this.handleOpenNotification
    });
    OneSignal.addEventListener("received", this.onReceived);
    OneSignal.addEventListener("opened", this.onOpened);
    OneSignal.addEventListener("registered", this.onRegistered);
    OneSignal.addEventListener("ids", this.onIds);

    if (!IOS) {
      OneSignal.inFocusDisplaying(0);
    }
  }

  componentWillUnmount() {
    AppState.removeEventListener("change", this.handleAppStateChange);
    OneSignal.removeEventListener("received", this.onReceived);
    OneSignal.removeEventListener("opened", this.onOpened);
    OneSignal.removeEventListener("registered", this.onRegistered);
    OneSignal.removeEventListener("ids", this.onIds);
  }

handleOpenNotification = (message, data, isActive) => {
    console.log("Notification", message, data, isActive);

    if (isActive) {
      // touchable banner displaying info from push notification
    } else {
      // act on data received from push notification
    }
  };

onReceived = notification => {
    console.log("Notification received: ", notification);
  };

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

حتى إذا كان تطبيقي مغلقًا - ليس في background AppState ، لكنه مغلق تمامًا - إذا نقرت على إشعار الدفع ، يتم استدعاء طريقة onOpened باستخدام openResult الكائن والبيانات المرتبطة به ، وأنا حر في إجراءات إعادة التشغيل المناسبة dispatch .

wkoutre هذا مثير للاهتمام ، هل يمكنك نشر ما هي إصدارات react-native ، react-native-onesignal وما إلى ذلك التي تستخدمها حاليًا؟ هل اختبرت هذا على كل من iOS و Android؟ هل أجريت اختبارًا مكثفًا لفتح التطبيق من خلال النقر على إشعار الدفع ، مع إغلاق التطبيق تمامًا في الوقت الذي تم فيه النقر على إشعار الدفع ، ووجدت أن طريقة onOpened تُسمى 100٪ من الوقت؟

هل يمكنك إجراء بعض الاختبارات لمعرفة ما إذا كان لا يزال يعمل بنسبة 100٪ من الوقت إذا قمت بتأخير تحميل PushNotificationHelper الخاص بك بشكل مصطنع ، على سبيل المثال عن طريق تعيين مهلة مع تأخير لمدة 5 ثوانٍ ، وبعد ذلك هل تريد تغيير شيء ما في الحالة للسماح بتثبيت PushNotificationHelper وتسجيل مستمعي الحدث باستخدام OneSignal؟

تضمين التغريدة

"react-native": "0.50.4"
"react-native-onesignal": "^3.0.7"

لقد اختبرت على كل من iOS و Android ، نعم. في كليهما ، 100٪ من الوقت:

  • التطبيق مغلق تمامًا
  • تم استلام إشعار الدفع
  • إعلام الدفع
  • تحميل التطبيق
  • يتم استدعاء onOpened بالبيانات من إشعار الدفع ، و openResult.notification.isAppInFocus === false

سأقوم بعمل setTimeout وأعود إليك.


EDIT1: لم أغير شيئًا على الإطلاق ، والآن فشل في نظام Android بنسبة 100٪ من الوقت.


EDIT2: تسبب إجراء تأخير $ # $ 5 $ # $ في عدم تنشيط setTimeout onOpened عند تحميل التطبيق من النقر فوق إشعار الدفع. ومع ذلك ، قمت بنقل كل شيء إلى أساليب دورة الحياة App.js - يتم تسجيل مكون الجذر الخاص بي في index.ios.js و index.android.js - و onOpened يسمى 100٪ في ذلك الوقت iOS ، وحوالي 50٪ من الوقت على Android.

لست متأكدًا من سبب عدم تناسق Android ، ولكن من الواضح أنها مشكلة. على Android ، عندما يكون التطبيق مغلقًا تمامًا ويأتي إشعار ، يمسح مصحح الأخطاء ويتم تحميل كل شيء في App.js حتى أقوم بإنشاء الفصل نفسه.

const IOSX = HEIGHT === 812 && PLATFORM === "ios";

const wrapperStyle = [Styles.flex1];
if (IOSX) wrapperStyle.push(Styles.backgroundDarkGray);

let SPLASH_TIME;

console.log(`Change to TRUE below to reset store state`);

const PURGE = DEV ? false : false;

if (DEV) SPLASH_TIME = 4000;
else SPLASH_TIME = 4000;

// const composeEnhancers = composeWithDevTools({
//   realtime: true,
//   port: 8000
// });

const composeEnhancers =
  typeof window === "object" &&
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ &&
  DEV
    ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
        // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
      })
    : compose;

const middlewares = [ReduxThunk];

// debugging tooling
// if (DEV) {
//   // add logger
// middlewares.push(logger)

//   // middlewares = [...middlewares, logger];
//   middlewares = [...middlewares];

// replace these transient reducers when they've been created

export const store = createStore(
  Reducers,
  {},
  composeEnhancers(
    applyAppStateListener(),
    applyMiddleware(...middlewares),
    autoRehydrate()
  )
);

// if (module.hot) {
//   // Enable hot module replacement for reducers
//   module.hot.accept(() => {
//     const nextRootReducer = require("./reducers/index").default;
//     store.replaceReducer(nextRootReducer);
//   });
// }

console.log(`right before APP`);

// Debugger logs everything before this line.

export default class App extends Component {
    ...
}

jordanmkoncz فضولي إذا كنت قد جربت هذه المكتبة: https://github.com/wix/react-native-notifications

حسنًا ، لدي حل بديل يعمل بنسبة 100٪ على كل من iOS و Android.

في App.js ولكن قبل أن أعلن عن مكون التطبيق الخاص بي ، لدي:

const handleOnOpened = openResult => {
  store.dispatch(setInitialNotification(openResult));
};

OneSignal.configure({});
OneSignal.addEventListener("opened", handleOnOpened);

... حيث setInitialNotification هو منشئ الإجراءات.

ثم ، عندما ينتهي تطبيقي (المثبت الآن) من إعادة الترطيب ، أتصل بـ:

this.setState({ rehydrated: true }, () => {
          OneSignal.removeEventListener("opened", handleOnOpened);
        });

يتم إرجاع تطبيقي - الملفوف بعلامة Provider - في طريقة render ، ويظهر شيئًا مثل ...

<Provider store={store}>
        <IphoneXAwareView style={wrapperStyle}>
          <StatusBar hidden={false} barStyle="light-content" />
          <MyAlert />
          <Loading />
          <ConnectedAppWithNavigationState />
          <PushNotificationHelper />
        </IphoneXAwareView>
      </Provider>

من هناك ، يتولى المكون PushNotificationHelper الاستماع إلى جميع إشعارات الدفع والتعامل معها.

bhoop لقد مر شهرين ، لذا لست متأكدًا مما إذا كنت لا تزال تبحث عن حل ولكن ... إذا كان الأمر كذلك ، فجرّب هذه المحاولة.

wkoutre هل يمكنك إعداد علاقات عامة مع تحديثات لملف المستند التمهيدي الذي يتضمن هذا الحل البديل للإعادة؟

تضمين التغريدة سأصل إليه هذا المساء

أدلى avishayil العلاقات العامة.

أواجه مشكلة تبدو هكذا. عندما يتم فتح التطبيق ، فإنه يعمل بشكل جيد مع جميع عمليات الاسترجاعات ، عندما يكون التطبيق في الخلفية أيضًا. ولكن ، إذا تلقيت دفعة ، يزداد رمز تطبيقي +1 ، ويعرض النظام شعاره مع محتوى الإخطار ولكن إذا تجاهلت الشعار وفتحت التطبيق من خلال الرمز (وليس عن طريق شعار الإشعار) ، فسيتم تجاهل رد الاتصال = [كيف امسك هذا ؟

  • اكسبو فصل التطبيق
  • رد فعل 16.3.1
  • واحد إشارة 3.2.5
  • اكسبو 27.0.1

brunoandradebr هذا هو السلوك المتوقع. فتح التطبيق من أيقونة التطبيق لا يأخذ في الحسبان أبدًا أي إشعار تلقيته. إنه يفتح التطبيق فقط.

إذا كنت ترغب في تغيير سلوك تطبيقك عند بدء تشغيله بناءً على ما إذا كان المستخدم قد تلقى إشعارًا ، فستحتاج إلى التحقق من ذلك بنفسك عند التشغيل.

هذا ليس صحيحا. عندما أقوم بفتح التطبيق بالأيقونة عند تشغيل التطبيق في الخلفية ، فإنه يتعامل مع دفع الإشعارات كما هو مطلوب. فقط عندما أقوم بإزالته من الذاكرة (التمرير السريع) ، ثم أفتحه بالرمز ، فلن يحدث شيء. كنت أقوم بالتحقيق وأعتقد أن XCode أوقف التطبيق وأغلق رابط oonesignal lib.

brunoandradebr ربما أكون قد أسيء فهم المشكلة التي تواجهها وأي رد (عمليات) اتصال تشير إليه.
إذا كان التطبيق يعمل في الخلفية ، فيمكنه التعامل مع أحداث received . ولكن إذا تم إيقاف التطبيق ، فلن يتمكن من الاستماع إلى أي حدث. الطريقة الوحيدة التي يمكن للإشعار من خلالها التفاعل مع أحد التطبيقات (لنظام iOS على الأقل) هي التفاعل مع الإشعار بأي طريقة.

عندما أقوم بإيقاف التطبيق ولدي إشعار ، إذا فتحت التطبيق عن طريق الرمز ، فلن يتمكن التطبيق من التعامل مع أحداث رد الاتصال ، ولكن إذا كان التطبيق يعمل في الخلفية ، وأنا أفتحه بالرمز ، تنطلق عمليات الاسترجاعات كما هو متوقع. فهمتك ؟

brunoandradebr أعتقد أنني فهمت الأمر ، وإذا لم أكن مخطئًا فهذا هو السلوك الذي وصفته في تعليقي السابق. على أي حال ، أشعر أن هذا خارج عن الموضوع وإذا كنت تعتقد أن لديك مشكلة في ذلك ، فيجب عليك فتح مشكلة منفصلة في الريبو.

jordanmkoncz يبدو أن لديك فهمًا جيدًا لقضايا إشارات الشخص الأصلية. الإصدارات التي أستخدمها هي إشارة تفاعلية أصلية: ^ 3.2.8 ومتفاعل أصلي: 0.56.0. تمكنت من تنفيذ معالجة الإشعارات في الخلفية والمقدمة ، لكنني أواجه مشكلة الآن عندما يتم إغلاق التطبيق ويتم النقر على إشعار. يعرض التطبيق فقط شاشة بيضاء فارغة لا تختفي إلا إذا قمت بإغلاقها وإعادة تشغيلها. لست متأكدًا من كيفية التعامل مع هذا الموقف حيث لا يمكنني العثور على أي وثائق على موقع OneSignal على الويب. إنه أمر محبط لأنني قضيت وقتًا في تعلم هذه المكتبة وتنفيذها ، والآن لست متأكدًا مما إذا كانت ستتمكن من التعامل مع حالة الاستخدام المهمة للغاية هذه. لقد قرأت حلًا بديلًا محتملًا لهذا أعلاه وهو تنفيذ مستمعي الأحداث في index.js ولكني أستخدم التنقل التفاعلي وأحتاج إلى الحصول على مرجع من الملاح الرئيسي الخاص بي والذي تم الإعلان عنه في App.js من أجل التنقل إلى شاشة مكدس متداخلة. سأكون ممتنًا حقًا لأي نصيحة يقدمها المرء في التعامل مع هذه المشكلة وكيف تم حلها. شكرا لك مقدما.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات