React-native-iap: 多次调用purchaseUpdatedListener

创建于 2020-02-03  ·  6评论  ·  资料来源: dooboolab/react-native-iap

版本的react-native-iap

4.3.0

本机版本

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条评论

我怀疑您在组件重新交付时已多次注册了purchaseListener。

谢谢,此后我已经使用钩子对此进行了重写,因此不会在每个渲染器上调用它。 我的错误是试图在类组件的文档中采用提供的示例并将其移植到功能组件。 图书馆的出色工作!

@cgathergood我也有这个问题。 您介意使用react挂钩发布事件处理程序代码吗?

@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 等级