react-native-iap icon indicating copy to clipboard operation
react-native-iap copied to clipboard

getAvailablePurchases returning "Error: An unknown error occurred" for TestFlight build

Open aadityapaliwal94 opened this issue 1 year ago • 17 comments

Description

Everything was working fine with react native IAP v9.x.x with us. I updated it due to a crash issue on crashlytics regarding the thread safety. Now I am using the latest version, everything is working fine but I am not able to fetch the getAvailablePurchases in the TestFlight build. It's working fine if I run it directly Run from Xcode.

Expected Behavior

It should return the available purchases

Screenshots

Environment:

  • react-native-iap: v12.7.4
  • react-native: 0.69.0
  • Platforms (iOS, Android, emulator, simulator, device): iOS

To Reproduce Steps to reproduce the behavior:

  1. Call getAvailablePurchases function in the TestFlight build.
  2. "Error: An unknown error occurred" returns.

[Optional] Additional Context


async getAvailablePurchases() {
    try {
      const availablePurchases = await RNIap.getAvailablePurchases()
      Utils.log('Store All Time Total Purchases ' + availablePurchases)
      const purchasesNeedsToCheck = []
      availablePurchases.forEach(element => {
        const txnMomentDate = moment(Number(element.transactionDate))
        const currentDateMoment = moment()
        const olderDays = Math.ceil(moment.duration(currentDateMoment.diff(txnMomentDate)).asDays())
        Utils.log('Transaction old days ' + olderDays)

        if (olderDays <= 35){ // #Warning: Only considering a month old txn. Need to change this if we have yearly subscription
          purchasesNeedsToCheck.push(element)
        }
      });

      Utils.log('Total Purchases needs to check ' + purchasesNeedsToCheck)

      var response = []
      for (const i in purchasesNeedsToCheck) {
        const purchase = purchasesNeedsToCheck[i];
        
        if (Utils.isSubsProduct(purchase.productId)) {
          Utils.log('Calling Validating purchase for productID : ' + purchase.productId)
          const result = await this.storeTransaction(purchase)
          if (result && result.productId) {
            response.push(result.productId)            
            SessionManager.instance.updatePurchasedData(purchase)            
            await SharedPreferences.storePurchasesProducts(result.productId);
            break        
          }
        }
      }

      Utils.log('Valid Purchases ' + JSON.stringify(response))
      return response
    } catch (error) {
      FirebaseManager.instance.recordError(IAP_ERROR_CODE, error);
      throw error
    }
  }

aadityapaliwal94 avatar Mar 08 '23 14:03 aadityapaliwal94

It's even not working with the older builds of TestFlight where I was using the older version of the IAP library v9.x.x. It's working in the production (App store) with the same account. It looks like TestFlight specific issue... :(

If I change the user from Media & Purchases, it seems working fine sometimes not always.

aadityapaliwal94 avatar Mar 09 '23 06:03 aadityapaliwal94

I have the same problem

xiaoosnggao avatar Mar 09 '23 10:03 xiaoosnggao

Also I have the same error.

dhyey001 avatar Mar 09 '23 11:03 dhyey001

I have the same problem on real ios device in sandbox mode! calling getAvailablePurchases On IOS sometimes gives me the expected array of purchases which i use to find the latestPurchase to check the purchase state(still valid or not) but sometimes it throws an error "Error: An unknown error occurred" while i had not changed anything in the code ! any suggestions please ! PS: i am using the method getAvailablePurchases which is exported by the hook useIAP and then using the value availablePurchases "react-native-iap": "12.7.3"

oussama1995 avatar Mar 10 '23 12:03 oussama1995

Same. Also get the same error with getPurchaseHistory(). This error still occurs when run from a useEffect where getProducts(...) and getSubscriptions(...) are successfully called.

mjfre avatar Mar 10 '23 22:03 mjfre

any news please @andresesfm

oussama1995 avatar Mar 21 '23 10:03 oussama1995

Capture the native logs and see if there's a native exception

andresesfm avatar Mar 21 '23 17:03 andresesfm

The same problem occurs in the sandbox.

hszouszcz avatar Mar 24 '23 13:03 hszouszcz

Still occurring for me on 12.10.5

mjfre avatar May 08 '23 01:05 mjfre

https://github.com/dooboolab-community/react-native-iap/issues/2455 Can anyone please suggest on this issue Please ?

Prathameshlabde avatar Jun 06 '23 10:06 Prathameshlabde

I have same problem. Can anyone fix this issue? Please help

vishalhyperspace avatar Jun 28 '23 10:06 vishalhyperspace

Still occurring for me on 12.10.7

DwaveVito avatar Sep 07 '23 09:09 DwaveVito

I fix this issue.

[Why] I use SK2 mode by default but isIosStorekit2 always return false

[How] setup mode before you call initConnection.

import { setup } from 'react-native-iap'
setup({ storekitMode: 'STOREKIT2_MODE' })

DwaveVito avatar Sep 08 '23 09:09 DwaveVito

Hi, Personally I use this : setup({ storekitMode: 'STOREKIT_HYBRID_MODE' })

cloud27 avatar Nov 14 '23 15:11 cloud27

if i include this than it's returning null array but i have purchased product in sandbox setup({ storekitMode: 'STOREKIT2_MODE' })

keval7169-ops avatar Feb 12 '24 09:02 keval7169-ops

@keval7169-ops

https://react-native-iap.dooboolab.com/docs/migrate_to_11.0.0#how-do-i-know-whats-the-minimum-version-of-ios-my-app-supports

Open ios/Podfile file and look for the following line: platform :ios, '15.0'

Check your iOS minimum version. Follow this docs try it.

DwaveVito avatar Feb 15 '24 06:02 DwaveVito

It's not just getAvailablePurchases, getPurchaseHistory also throws - in both cases it happens only if you set alsoPublishToEventListener to true (false by default).

I'm basically trying to implement the restore purchases.

App is (managed) expo dev-client build.

versions

"react-native-iap": "^12.13.1",
"expo": "^50.0.14",
"react-native": "^0.73.6",

env

sandbox account
iphone 13 mini
ios v17.3

init

export const initIap = async () => {
  setup({ storekitMode: "STOREKIT2_MODE" });

  setLoading(true);

  purchaseErrorListener((error) => {
    logError("iap purchaseErrorListener error", error);
  });
  purchaseUpdatedListener((purchase) => {
    logInfo("iap purchaseUpdatedListener purchase", purchase);

    processPurchase(purchase);
  });
  transactionListener((transaction) => {
    logInfo("iap transactionListener transaction", transaction);
  });

  try {
    // await initConnection();

    await Promise.all([
      getProducts({ skus: productSkus }).then(setProducts),
      getSubscriptions({ skus: subscriptionSkus }).then(setSubscriptions),
    ]);
  } catch (error) {
    logError("iap initIap error", error);
  }

  setLoading(false);
};

restore

export const restorePurchases = async () => {
  try {
    // const purchaseHistory = await getPurchaseHistory({
    //   onlyIncludeActiveItems: true,
    //   alsoPublishToEventListener: true,
    //   automaticallyFinishRestoredTransactions: false,
    // });
    // console.log("iap restorePurchases purchaseHistory", purchaseHistory);

    const availablePurchases = await getAvailablePurchases({
      onlyIncludeActiveItems: true,
      alsoPublishToEventListener: true,
      automaticallyFinishRestoredTransactions: false,
    });

    console.log("iap restorePurchases availablePurchases", availablePurchases);
  } catch (error) {
    console.log("iap restorePurchases error", error);
  }
};

image

miran248 avatar Apr 16 '24 19:04 miran248