4.3.0
0.60.5
Both
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);
});
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.
Real Device
I am suspecting you've registered purchaseListener multiple times when component rerenders.
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!
@cgathergood I'm having this issue too. Do you mind posting your event handler code using react hooks?
@cgathergood i would like to see code sample as well. i am little bit struggling with hooks.
@wootwoot1234 @osmantuna Can you please provide the event handler codes if you managed to fix it?
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();
};
}, []);
Most helpful comment
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):
inside your state component: