react-native-iap: [Android] purchaseUpdatedListener doesn't receive notification of successful purchase on device startup

Hi!

Description

Use case:

  • Initiate process of buying consumable product
  • Choose method “slow test card, approves after a few minutes”
  • Tap Buy
  • Wait to receive notification in purchaseUpdatedListener with pending purchase
  • Close the app
  • Check gmail for 2 letters: pending purchase, success purchase
  • Open app
  • purchaseUpdatedListener doesn’t receive any notifications

Expected Behavior

  • Initiate process of buying consumable product
  • Choose method “slow test card, approves after a few minutes”
  • Tap Buy
  • Wait to receive notification in purchaseUpdatedListener with pending purchase
  • Close the app
  • Check gmail for 2 letters: pending purchase, success purchase
  • Open app
  • purchaseUpdatedListener receive success notification

Screenshots

photo_2023-07-12 17 35 46 photo_2023-07-12 17 35 49 photo_2023-07-12 17 35 51

Environment:

  • react-native-iap: 12.10.5
  • react-native: 0.72.2
  • Platforms (iOS, Android, emulator, simulator, device): Android

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Reactions: 1
  • Comments: 23 (5 by maintainers)

Commits related to this issue

Most upvoted comments

@kesha-antonov I encountered a similar problem, and during my search for a solution, I stumbled upon a noteworthy pull request in the GitHub repository. This pull request involves the removal of the startListening() method. Intrigued, I decided to give it a shot by reintroducing this method, and lo and behold, the issue was resolved 🧐. While this might not be the ultimate solution, it serves as a solid foundation for me to build upon 😊.

Same problem is happening to me. I did the same as @zachariast and it also worked in my case, the android app starts to listen to events again when we open the app. But I wouldn’t call it a workaround since I had to mess with the lib’s code. This should be reviewed and brought back, or a better solution should be implemented if this part was indeed causing problems before. Also, startListening is marked as deprecated.

Screenshot 2023-09-12 at 18 24 19

@usmanabid94

async setPurchaseListener () {
  if (this.isPurchaseListenerSet) return

  this.isPurchaseListenerSet = true

  this.purchaseUpdateSubscription = purchaseUpdatedListener(this.processPurchase)

  this.purchaseErrorSubscription = purchaseErrorListener(
    ...
  )
}

async processUnfinishedPurchases () {
  try {
    // ON IOS IT WORKS AS EXPECTED: UNFINISHED PURCHASES LOADED ON APP STARTUP IN purchaseUpdatedListener
    if (CONSTANTS.IS_IOS)
      return

    const purchases = await getAvailablePurchases()
    for (const purchase of purchases)
      await this.processPurchase(purchase)
  } catch (e) {
    logException('processUnfinishedPurchases e', e)
  } 
}

...

await this.setPurchaseListener()
await this.processUnfinishedPurchases()

For non-consumable it’s correct logic I guess. You’ll get them either way in that method as I understand

I’ll check for consumable tomorrow

This used to work in the past, seems like it’s broken now.