React-native-iap: buyUpdatedListener вызывается повторно

Созданный на 3 февр. 2020  ·  6Комментарии  ·  Источник: dooboolab/react-native-iap

Версия react-native-iap

4.3.0

Версия react-native

0,60,5

Платформы, на которых вы столкнулись с ошибкой (IOS или Android или оба?)

Обе

Ожидаемое поведение

Следуя примеру, я хочу вызвать настраиваемый метод после покупки подписки. Насколько я понимаю, после подтверждения покупки слушатель должен быть удален? Я пробовал явно вызвать remove но безуспешно.

пример

 const purchaseListener = purchaseUpdatedListener(purchase => {
      const receipt = purchase.transactionReceipt;
      if (receipt) {
        callCustomEndpoint().then(result => {
          if(result){
            // Subscription is valid
            finishTransaction(purchase);
          }
        }) 
      };
      finishTransaction(purchase);
    });

Фактическое поведение

Метод callCustomEndpoint () вызывается несколько раз. Как я могу этого не допустить? Поскольку мне нужно только один раз попасть в эту конечную точку.

Я использую функциональный компонент вместо компонента класса, если это важно.

Протестированная среда (Эмулятор? Настоящее устройство?)

Настоящее устройство

Шаги по воспроизведению поведения

🙏 help wanted

Самый полезный комментарий

Собираюсь отложить свой раствор для крючков для тех, кому он понадобится в дальнейшем.

вне вашего компонента состояния (хотя, вероятно, работает и внутри):

var purchaseUpdateSubscription;
var purchaseErrorSubscription;
const loadIAPListeners = () => {
  initConnection(); // important, or else it won't trigger before a random state change
  purchaseUpdateSubscription = purchaseUpdatedListener(
    async (
      purchase: InAppPurchase | SubscriptionPurchase | ProductPurchase,
    ) => {
      console.log('purchaseUpdatedListener', purchase);
      let receipt = purchase.transactionReceipt;
      if (receipt) {
        apis.checkreceipt({data: purchase, platform: Platform.OS}); // I personally don't care about callback
        if (Platform.OS === 'ios') {
          await RNIap.finishTransactionIOS(purchase.transactionId);
        } else if (Platform.OS === 'android') {
          await RNIap.acknowledgePurchaseAndroid(purchase.purchaseToken);
        }
        await RNIap.finishTransaction(purchase, true);
        await RNIap.finishTransaction(purchase, false);
      } else {
        // Retry / conclude the purchase is fraudulent, etc...
      }
    },
  );
  purchaseErrorSubscription = purchaseErrorListener((error: PurchaseError) => {
    console.log('purchaseErrorListener', error);
  });
};

внутри вашего компонента состояния:

useEffect(() => {
    loadIAPListeners();
    return () => {
      purchaseUpdateSubscription.remove();
      purchaseErrorSubscription.remove();
    };
  }, []);

Все 6 Комментарий

Я подозреваю, что вы регистрировали PurchaListener несколько раз при повторной визуализации компонента.

Спасибо, с тех пор я переписал это с помощью хуков, так что он не вызывается при каждом рендере. Моя ошибка заключалась в попытке взять приведенный пример из документации компонента класса и перенести его на функциональный компонент. Отличная работа над библиотекой!

@cgathergood У меня тоже такая проблема. Вы не возражаете, чтобы опубликовать код обработчика событий с помощью обработчиков реакции?

@cgathergood Я тоже хотел бы увидеть образец кода. Я немного борюсь с крючками.

@ wootwoot1234 @osmantuna Не могли бы вы предоставить коды обработчиков событий, если вам удалось это исправить?

Собираюсь отложить свой раствор для крючков для тех, кому он понадобится в дальнейшем.

вне вашего компонента состояния (хотя, вероятно, работает и внутри):

var purchaseUpdateSubscription;
var purchaseErrorSubscription;
const loadIAPListeners = () => {
  initConnection(); // important, or else it won't trigger before a random state change
  purchaseUpdateSubscription = purchaseUpdatedListener(
    async (
      purchase: InAppPurchase | SubscriptionPurchase | ProductPurchase,
    ) => {
      console.log('purchaseUpdatedListener', purchase);
      let receipt = purchase.transactionReceipt;
      if (receipt) {
        apis.checkreceipt({data: purchase, platform: Platform.OS}); // I personally don't care about callback
        if (Platform.OS === 'ios') {
          await RNIap.finishTransactionIOS(purchase.transactionId);
        } else if (Platform.OS === 'android') {
          await RNIap.acknowledgePurchaseAndroid(purchase.purchaseToken);
        }
        await RNIap.finishTransaction(purchase, true);
        await RNIap.finishTransaction(purchase, false);
      } else {
        // Retry / conclude the purchase is fraudulent, etc...
      }
    },
  );
  purchaseErrorSubscription = purchaseErrorListener((error: PurchaseError) => {
    console.log('purchaseErrorListener', error);
  });
};

внутри вашего компонента состояния:

useEffect(() => {
    loadIAPListeners();
    return () => {
      purchaseUpdateSubscription.remove();
      purchaseErrorSubscription.remove();
    };
  }, []);
Была ли эта страница полезной?
0 / 5 - 0 рейтинги