Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

purchaseUpdatedListener is repeatedly called #926

Closed
cgathergood opened this issue Feb 3, 2020 · 6 comments
Closed

purchaseUpdatedListener is repeatedly called #926

cgathergood opened this issue Feb 3, 2020 · 6 comments
Labels
🙏 help wanted Extra attention is needed

Comments

@cgathergood
Copy link

cgathergood commented Feb 3, 2020

Version of react-native-iap

4.3.0

Version of react-native

0.60.5

Platforms you faced the error (IOS or Android or both?)

Both

Expected behavior

Following the example I want to call a custom method after my subscription has been purchased. It is my understanding that after acknowledging the purchase the listener should be removed? I have tried explicitly calling remove but had no success.

Example

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

Actual behavior

The callCustomEndpoint() method is being called multiple times. How can I stop this from happening? As I only need to hit this endpoint once.

I'm using a functional component instead of class component if it's important.

Tested environment (Emulator? Real Device?)

Real Device

Steps to reproduce the behavior

@hyochan hyochan added the 🙏 help wanted Extra attention is needed label Feb 5, 2020
@hyochan
Copy link
Member

hyochan commented Feb 5, 2020

I am suspecting you've registered purchaseListener multiple times when component rerenders.

@cgathergood
Copy link
Author

Thanks, I have since rewritten this using hooks so that it isn't called on each render. My mistake was trying to take the provided example in the docs of a class component and port it to a functional component. Great work on the library!

@wootwoot1234
Copy link
Contributor

@cgathergood I'm having this issue too. Do you mind posting your event handler code using react hooks?

@osmantuna
Copy link

@cgathergood i would like to see code sample as well. i am little bit struggling with hooks.

@aravi365
Copy link

@wootwoot1234 @osmantuna Can you please provide the event handler codes if you managed to fix it?

@heidji
Copy link

heidji commented Aug 21, 2020

I am going to put down my solution for hooks for those who will need it later on.

outside your state component (though probably works also inside):

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

inside your state component:

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🙏 help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

6 participants