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 being called multiple, sometimes 20+ times #1104

Closed
Pauly24 opened this issue Sep 8, 2020 · 30 comments
Closed

purchaseUpdatedListener being called multiple, sometimes 20+ times #1104

Pauly24 opened this issue Sep 8, 2020 · 30 comments
Labels
🤖 android Related to android 🙏 help wanted Extra attention is needed 🕵️‍♂️ need more investigation Need investigation on current issue

Comments

@Pauly24
Copy link

Pauly24 commented Sep 8, 2020

Version of react-native-iap

"react-native-iap": "^4.5.3"

Version of react-native

"react-native": "0.62.0"

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

iOS (havent tested on android yet)

Expected behavior

purchaseUpdatedListener should only be as called as many times as the component has mounted

Actual behavior

purchaseUpdatedListener was called 20 times in a couple of seconds, every so often when I open the app it get's called multiple times

Tested environment (Emulator? Real Device?)

Real device, sandbox env

Steps to reproduce the behavior

Follow instructions as per main page

I currently have purchaseUpdatedListener being attached to a listener in componentDidMount(), sometimes when I open up my app it will fire multiple times. This is happening on txns that I have called finishTransaction on. Is anyone seeing something like this?

@indapublic
Copy link

Same for me, but I call purchase flow in action

const { productId } = args
purchaseUpdatedListener(async (purchase) => {
	if (!purchase.transactionReceipt) {
		Alert("Error")
	}
	...
})
purchaseErrorListener(error => {
	...
})
await requestPurchase(productId, false)

@indapublic
Copy link

I have 4 test products and I receive purchaseUpdatedListener 4 times, but the purchase was requested only for one of them

@indapublic
Copy link

Tried finish those transactions but still multiple calls

@Pauly24
Copy link
Author

Pauly24 commented Sep 15, 2020

Is the item an auto-renew? I think what is happening is because it's in the sandbox the renew period is only 5 mins for my monthly subscription. So apple will send an event on each renew, so if the app was closed for 10 mins, that's 2 notifications I'll get when the app opens.

Can anyone confirm this is the expected behavior to get notifications on an auto-renew and not just on the purchase?

@indapublic
Copy link

My purchase is one time consumable

@EightPool
Copy link

Same here. At every auto-renew event, I receive the actual auto-renewable subscription and a few seconds later I receive a big chunk of 135 purchase objects from the purchaseUpdatedListener. I feel this is my entire purchase history. I tried to call both finishTransaction and finishTransactionIOS to consume the transactions but it doesn't change anything.

At the next auto-renew event, that big chunk of transactions is increasing (136, 137,...). The transactions are only my auto-renew subs. None of my consumable/non-consumable products appear on the list.

@manuel-grondona
Copy link

Same here, I confirm it calls the listener the same amount of times as the number of purchases in the purchase history.

@VictorKolb
Copy link

I have some problem. It is happening only when subscription is enabled.

@tecshogo
Copy link

tecshogo commented Sep 26, 2020

I had a similar experience with iOS 14.

My app sells an auto-renewal subscription.
I think this issue has occurred since I purchased the same subscription again.

The following link may be relevant to this issue.
https://developer.apple.com/forums/thread/659529

@hieutran24
Copy link

take a look this post
the problem is finishTransaction and finishTransactionIOS not work for iOS now, these alway return undefined , so that u can't finish transaction and they stuck in pending transaction. When u open your app, ALL pending transactions will be handled in purchaseUpdatedListener ... so that's why u got 20+ times.
:((( someone fix this plsssssss

@hyochan hyochan added 🤖 android Related to android 🙏 help wanted Extra attention is needed labels Oct 26, 2020
@hyochan
Copy link
Member

hyochan commented Oct 26, 2020

take a look this post
the problem is finishTransaction and finishTransactionIOS not work for iOS now, these alway return undefined , so that u can't finish transaction and they stuck in pending transaction. When u open your app, ALL pending transactions will be handled in purchaseUpdatedListener ... so that's why u got 20+ times.
:((( someone fix this plsssssss

#1160 (comment)
I've posted a reply here and actually it is expected that finishTransaction does not resolve promise.
We need to verify that it actually finishes transaction by putting log in iOS side and check if it enters an if statement.

@hyochan hyochan added the 🕵️‍♂️ need more investigation Need investigation on current issue label Oct 26, 2020
@edo1493
Copy link

edo1493 commented Nov 4, 2020

I am seeing the same as mentioned here: #1172 (comment).

@laurpantelimon
Copy link

On android, after a requestPurchase, the purchaseUpdatedListener is called exactly 3 times with the same payload and I therefore make 3 circles of "give rewards in backend -> finish transaction". The first time it is all good but the second and third time they fail because the transaction is finished the first time. On IOS it's all good, only one time the purchaseUpdatedListener is called.The purchase history in empty.
Any ideas?

@andresesfm
Copy link
Collaborator

Can somebody please validate this is the case in 6.1.0 or newer? The IapExample app is back in working order and I can't replicate this issue

@marcpechaitis
Copy link
Contributor

@andresesfm I am encountering this issue on 6.2.1.

My code (note, I'm testing Android right now so I'm only using consumePurchaseAndroid() because finishTransaction() is a hot mess):

  useEffect(() => {
    const checkCurrentPurchase = async (purchase?: Purchase): Promise<void> => {
      console.log('🔳🔲🔳🔲🔳🔲', 'checkCurrentPurchase');
      if (purchase) {
        const receipt = purchase.transactionReceipt;
        console.log('🔳🔳🔳', receipt);
        if (receipt) {
          try {
            // const ackResult = await finishTransaction(purchase);
            await RNIap.consumePurchaseAndroid(purchase.purchaseToken);
            console.log('🔲🔲🔲 ackResult', ackResult);
          } catch (ackErr) {
            setProcessingPurchase(false);
            console.warn('🔷🔷🔷 ackErr', ackErr);
          }
        }
      }
    };
    checkCurrentPurchase(currentPurchase);
  }, [currentPurchase, finishTransaction]);

result:

[Wed Jun 23 2021 08:55:22.820]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:22.875]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:24.392]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:24.454]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:25.920]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:25.979]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:27.552]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:27.609]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:29.830]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:29.880]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:30.683]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:30.743]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:32.271]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:32.327]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:34.340]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:34.410]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:35.988]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:36.480]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:37.639]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:37.691]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:39.210]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:39.269]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:40.811]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:40.875]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:42.346]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:42.405]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:43.916]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:43.983]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:45.443]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:45.502]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:47.200]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:47.610]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:48.506]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:48.558]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:50.550]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:50.118]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:51.591]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:51.654]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:53.134]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:53.191]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:54.674]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:54.735]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:56.170]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:56.226]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:57.774]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:57.838]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:55:59.281]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:55:59.342]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:56:00.845]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:56:00.910]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:56:02.357]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:56:02.409]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:56:04.312]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:56:04.387]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:56:05.932]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:56:05.997]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:56:07.721]  LOG      🔳🔲🔳🔲🔳🔲 checkCurrentPurchase
[Wed Jun 23 2021 08:56:07.746]  LOG      🔳🔳🔳 {"orderId":"GPA.3344-3869-5501-90751","packageName":"com.sugarloafappcompany.bingo","productId":"bingo.consumable.dollar","purchaseTime":1624460117834,"purchaseState":0,"purchaseToken":"adhfehbkneedajpdbpaocmhk.AO-J1OyoT5Od2NpKrOG2AJ81z0VfIWakGQW-10Y3grx9J3XlHWXJS-hlZ5PMyDx8duq8_y-PlAnhWMlC6xtPE_4kXZJXbTtjbN8DZOJ_ppZPdfJKPkiTvZJmDD7NeQWnDOgzCeZqwRU8","acknowledged":false}
[Wed Jun 23 2021 08:56:07.746]  LOG      [CodePush] Sync already in progress.
[Wed Jun 23 2021 08:56:07.746]  LOG      [CodePush] Sync already in progress.
[Wed Jun 23 2021 08:56:07.747]  LOG      [CodePush] Sync already in progress.
[Wed Jun 23 2021 08:56:07.747]  LOG      [CodePush] Sync already in progress.
[Wed Jun 23 2021 08:56:07.748]  LOG      [CodePush] Sync already in progress.
[Wed Jun 23 2021 08:56:07.749]  LOG      [CodePush] Sync already in progress.
[Wed Jun 23 2021 08:56:07.749]  LOG      [CodePush] Sync already in progress.
[Wed Jun 23 2021 08:56:07.749]  LOG      [CodePush] Sync already in progress.
[Wed Jun 23 2021 08:56:07.752]  LOG      [CodePush] Sync already in progress.
[Wed Jun 23 2021 08:56:07.753]  LOG      [CodePush] Sync already in progress.
[Wed Jun 23 2021 08:56:07.754]  LOG      [CodePush] Sync already in progress.
[Wed Jun 23 2021 08:56:07.754]  LOG      [CodePush] Sync already in progress.
[Wed Jun 23 2021 08:56:07.754]  LOG      [CodePush] Sync already in progress.
[Wed Jun 23 2021 08:56:07.764]  LOG      [CodePush] Sync already in progress.
[Wed Jun 23 2021 08:56:07.767]  LOG      App has come to the foreground!
[Wed Jun 23 2021 08:56:09.433]  LOG      [CodePush] Checking for update.
[Wed Jun 23 2021 08:56:09.566]  WARN     🔷🔷🔷 ackErr [ReferenceError: Can't find variable: ackResult]
[Wed Jun 23 2021 08:56:09.617]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:09.758]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:09.759]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:09.771]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:09.837]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:09.859]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:09.926]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:09.963]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:09.999]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.580]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.920]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.128]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.165]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.199]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.236]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.270]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.303]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.339]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.392]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.435]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.456]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.506]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.540]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.572]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.606]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.642]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.678]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:10.970]  LOG      [CodePush] Reporting binary update (8.0.2)
[Wed Jun 23 2021 08:56:10.987]  WARN     🔷🔷🔷 ackErr [Error: Purchase failed with code: 8]
[Wed Jun 23 2021 08:56:12.967]  LOG      [CodePush] Report status failed: {"appVersion":"8.0.2"}
[Wed Jun 23 2021 08:56:13.250]  LOG      [CodePush] App is up to date.

note 1 - I have attempted purchases many many times this morning, and after each attempt the number of these loops increases
note 2 - I'm not sure why I'm getting "Error: Purchase failed with code 8"? The purchase is getting consumed, but according to this error code 8 = "Failure to consume item since it is not owned"?

On the surface it does seems possible the purchaseUpdatedListener is not getting removed properly, and maybe this is happening because I have been hot reloading the app?

Thanks for looking into this!

@andresesfm
Copy link
Collaborator

@marcpechaitis thank you for the details. I have created a PR with fixes to multiple billing clients being created: #1388 this could be the solution to your problems. Any help testing it would be appreciated.

@marcpechaitis
Copy link
Contributor

marcpechaitis commented Jun 26, 2021

@andresesfm awesome thanks for the hard work on this! I've been out of town and am just now able to get back at this. I have a question about your PR (#1338) -- I reviewed your changes and I see the recommendation related to the connection lifecycle and, essentially, "connect/init as soon as you can, not right before you need it" which makes sense... but does the useIAP hook honor that? I have written my code around useIAP() and will have to do some refactoring away from that in order to properly test your PR, right? Another way to put it, does invoking useIAP() throughout the app mean multiple attempts to init are made?

High-level: I have 2 screens where I'm using useIAP (one for consumables, the other for a non-consumable). When I invoke useIAP on either screen doesn't that kick off another init? And on top of that, I'm loading the currentPurchase & currentPurchaseError listeners in my main App.tsx file -- which results in another init happening?

@marcpechaitis
Copy link
Contributor

@andresesfm I'm having issues trying to get your fork to work in my project:

error: Error: While trying to resolve module `react-native-iap` from file `/Users/marcpechaitis/Dropbox/Develop/rn/sandbox/iTour/helpers/router.tsx`, the package `/Users/marcpechaitis/Dropbox/Develop/rn/sandbox/iTour/node_modules/react-native-iap/package.json` was successfully found. However, this package itself specifies a `main` module field that could not be resolved (`/Users/marcpechaitis/Dropbox/Develop/rn/sandbox/iTour/node_modules/react-native-iap/index.js`. Indeed, none of these files exist:

  * /Users/marcpechaitis/Dropbox/Develop/rn/sandbox/iTour/node_modules/react-native-iap/index.js(.native|.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx|.ios.svg|.native.svg|.svg)
  * /Users/marcpechaitis/Dropbox/Develop/rn/sandbox/iTour/node_modules/react-native-iap/index.js/index(.native|.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx|.ios.svg|.native.svg|.svg)
    at ResolutionRequest.resolveDependency (/Users/marcpechaitis/Dropbox/Develop/rn/sandbox/iTour/node_modules/metro/src/node-haste/DependencyGraph/ResolutionRequest.js:65:15)
    at DependencyGraph.resolveDependency (/Users/marcpechaitis/Dropbox/Develop/rn/sandbox/iTour/node_modules/metro/src/node-haste/DependencyGraph.js:287:16)
    at Object.resolve (/Users/marcpechaitis/Dropbox/Develop/rn/sandbox/iTour/node_modules/metro/src/lib/transformHelpers.js:267:42)
    at /Users/marcpechaitis/Dropbox/Develop/rn/sandbox/iTour/node_modules/metro/src/DeltaBundler/traverseDependencies.js:434:31
    at Array.map (<anonymous>)
    at resolveDependencies (/Users/marcpechaitis/Dropbox/Develop/rn/sandbox/iTour/node_modules/metro/src/DeltaBundler/traverseDependencies.js:431:18)
    at /Users/marcpechaitis/Dropbox/Develop/rn/sandbox/iTour/node_modules/metro/src/DeltaBundler/traverseDependencies.js:275:33
    at Generator.next (<anonymous>)
    at asyncGeneratorStep (/Users/marcpechaitis/Dropbox/Develop/rn/sandbox/iTour/node_modules/metro/src/DeltaBundler/traverseDependencies.js:87:24)
    at _next (/Users/marcpechaitis/Dropbox/Develop/rn/sandbox/iTour/node_modules/metro/src/DeltaBundler/traverseDependencies.js:107:9)

(I'm don't have tons of experience with git, so I appreciate any advice you can give to help me proceed?)

Here is how I tried to use your fork:

// 1st remove old version
> yarn remove react-native-iap
// use forked version
> yarn add https://github.com/andresesfm/react-native-iap.git 
// clean & run
> cd android &&./gradlew clean && cd .
> react-native run-android

@marcpechaitis
Copy link
Contributor

@andresesfm I just wanted to report back that I made some changes and have stopped seeing the "purchaseUpdatedListener being called multiple times" issue on my end (despite not using your fork).

I took the advice in the documentation of your fork and removed a couple extraneous calls I was making to initConnection() at various spots throughout my code. Now I am letting that happening solely via the call to the useIAP() hook in a useEffect() where I set the currentPurchase and currentPurchaseError in my main App.tsx file.

@StefanNedelchev
Copy link

StefanNedelchev commented Jun 30, 2021

Probably the best solution is - on iOS call a chain of clearProductsIOS() and clearTransactionIOS() before initializing your transaction listeners. Additionally - don't use getAvailablePurchases() on iOS if you want to restore purchases. The better solution is to restore the receipt (getReceiptIOS()) and pass it to validateReceiptIos(). If you are using auto-renewable subscriptions you can look for the pending_renewal_info array returned by validateReceiptIos() as it contains info for currently ongoing (or canceled) subscriptions. You can check if a subscription is still active by verifying that the property auto_renew_status is '1' and the property expiration_intent is not present.

@andresesfm
Copy link
Collaborator

Thank you all for the info. I'm closing it, but feel free to reopen if needed

@Haseeba393
Copy link

I'm using latest version 12.10.2 and still getting this problem. Can you please help me out?

@VictoriaStudios
Copy link

VictoriaStudios commented Mar 31, 2023

Getting the same problem here... .Will probably need to code a workaround.... Maybe have a timeout that prevents a second trigger of the assigned side effect.
Edit: I'm on Android, it happens on a physical device.

@Haseeba393
Copy link

In getting the same issue on latest version ios

@VictoriaStudios
Copy link

VictoriaStudios commented Mar 31, 2023

So here's my solution with comments:

let checkCount = 0
// this was the only way of stopping react native from generating an unpredictable amount of subscriptions
const [subscriptionsBound, setSubscriptionsBound] = useState(false)

useEffect(() => {
    if (!subscriptionsBound) {
        const purchaseUpdateSubscription = IAP.purchaseUpdatedListener((purchase) => {
            checkCount++
            // insert your number of repeated subscription calls below
            if (checkCount >= 2) {
                console.log ('checkCount reached two, checking purchase')
                checkPurchase(purchase)
                checkCount = 0
            }
        })

        //... other effects
        setSubscriptionsBound(true)
       //just to make sure react doesn't call multile useEffects
        console.log('useEffect called')
        return () => {
            purchaseUpdateSubscription.remove()
            purchaseErrorSubscription.remove()
        }
    }
}, [])

@VictoriaStudios
Copy link

VictoriaStudios commented Apr 2, 2023

Another update: I noticed that the multiple binding only happens at the very start of the App. If I bind the purchaseUpdate to data that is later fetched, the error does not happen. So I basically accidentally fixed it by having an if-statement and a dependency on data that were later fetched:

   useEffect(() => {
        if (uData) {
            console.log('Binding purchase Subscriptions, uData:')
            console.log(uData)
            const purchaseUpdateSubscription = IAP.purchaseUpdatedListener((purchase) => {
                console.log('update Subscription called')
                checkPurchase(purchase, uData)
            })


            return () => {
                purchaseUpdateSubscription.remove()
            }
        }
    }, [uData])

@Anupamchap
Copy link

Issue still exist in the latest version of react-native-iap, purchaseUpdatedListener is getting called multiple times. Please share if someone has resolution for this issue.

@carlosmellado
Copy link

Having the same problem. All works as expected on Android but I'm having issues with this on iOS.
clearTransactionIOS() is not solving the issue.

@SufianBabri
Copy link
Contributor

It seems to happen on Android if you have multiple open connections (which can happen pretty easily when running with Metro, i.e. initConnection got called more times than endConnection). Also, see this answer which is related to native Android code

In my testing, the function passed to purchaseUpdatedListener gets called twice unless I call endConnection before calling initConnection. This seems weird, maybe it is specific to debug builds?

@mrtawil
Copy link

mrtawil commented Feb 14, 2024

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤖 android Related to android 🙏 help wanted Extra attention is needed 🕵️‍♂️ need more investigation Need investigation on current issue
Projects
None yet
Development

No branches or pull requests