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

getAvailablePurchases() not getting resolved on iOS 16 #1984

Closed
Mi6u3l opened this issue Sep 21, 2022 · 23 comments
Closed

getAvailablePurchases() not getting resolved on iOS 16 #1984

Mi6u3l opened this issue Sep 21, 2022 · 23 comments

Comments

@Mi6u3l
Copy link

Mi6u3l commented Sep 21, 2022

Description

getAvailablePurchases() is not resolving on iOS 16.
It is working fine on iOS 15 and 15.5.

Expected Behavior

getAvailablePurchases() should return a success or error response

Environment:

react-native-iap: 10.1.3 and 11.0.0-rc.3
react-native: 0.67.0
Platforms iOS (any simulator with iOS 16) tested on physical device iPhone 13 mini device (iOS 16)

@andresesfm
Copy link
Contributor

@Mi6u3l when trying 11.0.0-rc.3 did you enable Storekit2?

@Mi6u3l
Copy link
Author

Mi6u3l commented Sep 21, 2022

@andresesfm I did not. Apologies if it was a requirement and I missed it.
I expected that getAvailablePurchases() would work as usual, with my existing subscriptions created on app store connect.

@andresesfm
Copy link
Contributor

Please help us test the recently released 11.0.0-rc.4 here are the migration instructions: https://github.com/dooboolab/react-native-iap/blob/next/docs/docs/migrate_to_11.0.0.md . The main objective of this release is to use storekit2 which is for ios 15 and up

@manuelbieh
Copy link
Contributor

manuelbieh commented Sep 22, 2022

Running into the same issue here. I have just upgraded to 11.0.0-rc.4 and some weird things are going on in my app.

I have imported the named export { setup } from react-native-iap (not setup as the migration guide states at this point (PR here))

I have then called

setup({ storekitMode: 'STOREKIT2_MODE' });

very early in my App.tsx and before wrapping my app in the withIAPContext() HOC (also tried STOREKIT_HYBRID_MODE but I got the same error).

I am then using the following App.tsx (simplified):

import { getAvailablePurchases, setup, useIAP, withIAPContext } from 'react-native-iap';

setup({ storekitMode: 'STOREKIT2_MODE' });

const App = () => {
  const { connected } = useIAP();

  const loadSubscriptions = useCallback(async () => {
      if (connected) {
        await getAvailablePurchases();    
      }
  }, [connected]);

  useEffect(() => {
    loadSubscriptions();
  }, [loadSubscriptions]);

  return null;
}

export default withIAPContext(App);

Once I do that I get a fat red native exception:

Exception 'getAvailableItems::resolve:reject: is not a recognized Objective-C method.' was thrown while invoking getAvailableItems on target RNIapIosSk2 with params (
    0,
    3894,
    3895
)
callstack: (
 0   CoreFoundation                      0x00000001addae254 42C5C917-0447-3995-B50F-DE4D132C2435 + 41556
 1   libobjc.A.dylib                     0x00000001a7173a68 objc_exception_throw + 60
 2   Foundation                          0x00000001a8732958 AA92CD58-561A-3414-92F4-B4120298B39A + 5531992
 3   Unbogify-beta                       0x00000001051afeb8 -[RCTModuleMethod processMethodSignature] + 808
 4   Unbogify-beta                       0x00000001051b6258 -[RCTModuleMethod invokeWithBridge:module:arguments:] + 136
 5   Unbogify-beta                       0x00000001051ba1b8 _ZN8facebook5reactL11invokeInnerEP9RCTBridgeP13RCTModuleDatajRKN5folly7dynamicEiN12_GLOBAL__N_117SchedulingContextE + 1108
 6   Unbogify-beta                       0x00000001051b9b88 _ZZN8facebook5react15RCTNativeModule6invokeEjON5folly7dynamicEiENK3$_0clEv + 144
 7   Unbogify-beta                       0x00000001051b9aec ___ZN8facebook5react15RCTNativeModule6invokeEjON5folly7dynamicEi_block_invoke + 28
 8   libdispatch.dylib                   0x00000001b52284b4 C663D847-B94F-3FB0-9254-32EDBC55315E + 9396
 9   libdispatch.dylib                   0x00000001b5229fdc C663D847-B94F-3FB0-9254-32EDBC55315E + 16348
 10  libdispatch.dylib                   0x00000001b5231694 C663D847-B94F-3FB0-9254-32EDBC55315E + 46740
 11  libdispatch.dylib                   0x00000001b52321e0 C663D847-B94F-3FB0-9254-32EDBC55315E + 49632
 12  libdispatch.dylib                   0x00000001b523ce10 C663D847-B94F-3FB0-9254-32EDBC55315E + 93712
 13  libsystem_pthread.dylib             0x00000001fa6ccdf8 _pthread_wqthread + 288
 14  libsystem_pthread.dylib             0x00000001fa6ccb98 start_wqthread + 8
)

RCTFatal
facebook::react::invokeInner(RCTBridge*, RCTModuleData*, unsigned int, folly::dynamic const&, int, (anonymous namespace)::SchedulingContext)
facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int)::$_0::operator()() const
invocation function for block in facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int)
C663D847-B94F-3FB0-9254-32EDBC55315E
C663D847-B94F-3FB0-9254-32EDBC55315E
C663D847-B94F-3FB0-9254-32EDBC55315E
C663D847-B94F-3FB0-9254-32EDBC55315E
C663D847-B94F-3FB0-9254-32EDBC55315E
_pthread_wqthread
start_wqthread

Anything I'm doing wrong here? I'm testing on a real iPhone 13 with iOS 16, XCode 14, React Native 0.68.2

@andresesfm
Copy link
Contributor

That looks correct @manuelbieh . (Thank you for the PR) I will have a look

@manuelbieh
Copy link
Contributor

manuelbieh commented Sep 22, 2022

I double checked and created this minimum reproducible example in my app folder to sort out possible side effects and I still get the error there:

import { useCallback, useEffect } from 'react';
import { getAvailablePurchases, setup, useIAP, withIAPContext } from 'react-native-iap';

setup({ storekitMode: 'STOREKIT2_MODE' });
// setup({ storekitMode: 'STOREKIT_HYBRID_MODE' });

const App = () => {
    const { connected } = useIAP();

    const loadSubscriptions = useCallback(async () => {
        if (connected) {
            await getAvailablePurchases();
        }
    }, [connected]);

    useEffect(() => {
        loadSubscriptions();
    }, [loadSubscriptions]);

    return null;
};

export default withIAPContext(App);

that's my complete RN app at this point and I'm getting the error as described above. Other calls like await getSubscriptions({ skus: SUBSCRIPTION_SKUS }) work fine after changing the function signature from an array to an object as described in the 10.0.0 migration guide. It's only the getAvailablePurchases call that's failing so far.

@derRaab
Copy link

derRaab commented Sep 22, 2022

We're also running into this problem on iOS 16 with version 10.1.3, so I tried to build our master branch, which uses 7.5.6: Similar behaviour.

So right now we can't release an update and I wonder if this might still work with a different library version?

I hope this can somehow be fixed soon (we would help, but our insights are very minimal, especially on the native side of things).

@derRaab
Copy link

derRaab commented Sep 22, 2022

A small side note that might not really be useful. We do have one TestFlight user on iPhone 12 mini with iOS 16 who is able to start the application. So my guess is that this bug is somewhat related to the App Store user itself. But again - just a wild guess.

@Mi6u3l
Copy link
Author

Mi6u3l commented Sep 22, 2022

For me, it works in production. But not on development or Testflight

@andresesfm
Copy link
Contributor

Fix for reported crash: #1988

@andresesfm
Copy link
Contributor

Released fix as part of 11.0.0-rc.5

@mharrison-nzme
Copy link

For me, it works in production. But not on development or Testflight

Experiencing the same symptoms on 7.5.1
React native 63.3

Blocked doing any releases until we figure out whats going on. Id love to try the v11 alpha but our react native version will not support it

@derRaab
Copy link

derRaab commented Sep 23, 2022

@andresesfm Thank you very much! So we need to migrate from 10 to 11 or is this also fixable for version 10?

@Aiosa
Copy link

Aiosa commented Sep 23, 2022

Installed the 11.0.0-rc.5 but the function still does not resolve. Nor does request[Purchase|Subscription]. Moreover, getSubscriptions results in

[TypeError: undefined is not an object (evaluating 'skus.includes')]

maybe I just messed up the installation...

yeah edit: porting to a new version changes the positional parameters to object parameters - thanks @manuelbieh. Though a good practice is to release first a version that supports both (typeof firstarg === "object" && ...) with deprecation message in the case of positional arguments...

also thanks @derRaab for the tip - I had to remove and add again the sandbox account on the device, what helped in the end was to raise the minimal iOS (target version) - probably because Storekit2 works on 15+...

@manuelbieh
Copy link
Contributor

11.0.0-rc.5 works for me. Thanks!

@Aiosa you should check the 10.0.0 migration guide.

@derRaab
Copy link

derRaab commented Sep 23, 2022

@Aiosa For me it does resolve now in version 11.0.0-rc.5, after I found out that my sandbox user wasn't able to connect. So doublecheck you device sandbox user is correctly logged in.

@andresesfm
Copy link
Contributor

yeah edit: porting to a new version changes the positional parameters to object parameters - thanks @manuelbieh. Though a good practice is to release first a version that supports both (typeof firstarg === "object" && ...) with deprecation message in the case of positional arguments...

That would be a nice contribution to the project @Aiosa

@derRaab
Copy link

derRaab commented Sep 24, 2022

@andresesfm Thanks for your great work! It's kind of weird, but with 11.0.0-rc.6 with STOREKIT1_MODE we did experience this problem again (on iPhone 14 Pro). So I did log out the sandbox user on my device. Still didn't work. Then I logged the sandbox user back in again and now it seems to work again. It did resolve for other testers sometimes with and sometimes without sandbox user. So I will now test the library in hybrid mode - maybe that will do the trick. I just wanted to leave a note that there seems to be still an issue. :(

@andresesfm
Copy link
Contributor

@derRaab there's a report here: #1987 of a problem caused by transactions being automatically finished the first time you call getAvailableItems the first time. Can you please confirm that's the issue you are experiencing?

@derRaab
Copy link

derRaab commented Oct 12, 2022

@andresesfm After many days of refactoring and analysing we are still experiencing this kind of problem, but the circumstances become a little more clear now. Maybe there is now a way to understand this a little more?

We are only using only STOREKIT1_MODE since we need to support iOS 12 and we also have an already existing receipt validation process which relies on the transactionReceipt value.

This is something I can now reproduce and I hope you can too:

Invoking getAvailablePurchases() on a real device connected to Xcode WITHOUT and logged in app store sandbox user will not resolve! BUT it will resolve, if I'm logged in with a sandbox user.

I tested with all boolean combinations of alsoPublishToEventListener and automaticallyFinishRestoredTransactions.

Side note: If I try to purchase a product without a logged in sandbox user, the app will request to log into an Apple-ID, so I would expect to trigger such a dialog for getAvailablePurchases() as well. OR at least the api throws an error we can handle within the app.

I assume somewhere in the library code the execution stops if no app store user is available to restore purchases from?

We are experiencing this non resolving problem mainly with TestFlight users and this is very hard to debug, because not all users have that problem. Maybe you can look into this again?

Environment:

react-native-iap: 12.0.3
react-native: 0.68.3
Platforms iOS 16

@andresesfm andresesfm reopened this Oct 12, 2022
@andresesfm
Copy link
Contributor

@derRaab can you please post some (native) logs of when that occurs?
In particular, one of these should be printed:

PaymentQueueRestoreCompletedTransactionsFinished

or

restoreCompletedTransactionsFailedWithError

@derRaab
Copy link

derRaab commented Oct 13, 2022

@andresesfm Unfortunately none of them did appear in my logs. A colleague on the other hand did receive it only once. 🤦🏻

I'm still investigating...

@andresesfm
Copy link
Contributor

Doing some research on this I found the following:

Call [...] SKPaymentQueue.restoreCompletedTransactions asks for Appstore credential
When we build the app from Xcode or download from Testflight, receipt is not bundled within the app since the app is not downloaded from AppStore. We can use SKReceiptRefreshRequest to download receipt from sandbox Appstore
restoreCompletedTransactions updates app receipt

from:
onmyway133/blog#703

So it might not be an issue in production. We can reopen if this doesn't apply in your case.

Please consider supporting the project via Ko-fi or patreon. Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants