React-native-iap: getAvailablePurchases never resolves if initConnection has not been run

Created on 30 Apr 2020  ·  10Comments  ·  Source: dooboolab/react-native-iap

Version of react-native-iap

4.4.8

Version of react-native

0.61.4

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

iOS

Expected behavior

getAvailablePurchases() to reject with error when something is wrong.

Actual behavior

getAvailablePurchases() never ever returns the promise

Tested environment (Emulator? Real Device?)

Real device

Steps to reproduce the behavior

Call getAvailablePurchases without having called initConnection beforehand.

❓ question

Most helpful comment

Also, if initConnection is a required step to run before doing anything else, wouldn't it be better if react-native-iap kept track of that internally?

All 10 comments

This is expected from the latest version. You always need to init the connection to start whatever inside the billing SDK.

@hyochan But having a promise which never resolves or rejects is an anti-pattern, no? I mean it's basically "hanging" the software. Why not reject getAvailablePurchases with an error?

@AdamGerthel Oh that is a good point. I might have to see where we can throw an error when billing is not ready!

Hey @hyochan, I believe, you should update README examples to include .initConnection() call. As of now, it is absolutely not clear from README it should be called. And to make it more confusive, everything seems to work without it on Android, thus the problem appears out of nowhere during a transition from Android to iOS.

Also, if initConnection is a required step to run before doing anything else, wouldn't it be better if react-native-iap kept track of that internally?

And when to run initConnection? Should I run it after app launch and keep active for the whole time? Because docs say

Before you request any purchase, you should set purchaseUpdatedListener from react-native-iap. It is recommended that you start listening to updates as soon as your application launches

and to receive events from purchaseUpdatedListener, the initConnection needs to be ran.

@CptFabulouso ¯_(ツ)_/¯

After wasting some time trying to make it work for iOS App Store, it seems there is no way to reliably handle iOS purchases (at least subscriptions), without your own server infrastructure able to level out all issues (which I was trying to do, and which works fairly well for Android / Google.Play). At that point I just found and decided to give at try to https://www.revenuecat.com. Can't say yet how well it works overall, but at least the initial setup and testing on iOS took me very small time, went smoothly, and so far everything works according to common sense, unlike the native iOS IAP.

@birdofpreyru What issues were you having with iOS? We'll also implementing subscriptions and everything seems working atm, just a little bit confused how it should be handled _correctly_. I heard positive comments about revenuecat, maybe we'll switch too, but with client we want to try it "natively" first.

@CptFabulouso First I experienced very inconsistent results from getAvailablePurchases(), at least in Sandbox it returns me multiple purchases for the same subscription (and I am taking into account that iOS creates new purchases when renews subscriptions); and it seems to be not an issue with this library _per se_, but problems with iOS IAP. Then, I figured out that iOS docs tell to not verify receipts inside an app, and tell it should be done only at server you control. Then, after some more reading around Internet it looked like other people complain about such stuff with iOS IAP, and kind of agree that you may only rely on receipts, and you really should keep the track of subscriptions and expirations yourself to level out any possible issues.

RevenueCat seems to take care about it: it returns you the object with currently active subscription, and purchases; and takes care about caching / updating these data behind the scene. Their react-native SDK exposes the interface very similar to react-native-iap, but they are able to do the internal stuff better, probably just because they do server-side handling of that stuff.

And then in my case I am also doing a web version of my app, and it looks like RCat will also allow to setup purchases with Stripe there easily, without a need to implementing my own backend stuff. Still to see how it works out, but as of now it seems plausible and adds points to RCat.

@birdofpreyru Thank you for this, good to know what to look out for. We'll be handling most of the stuff you write on BE, so basically what RCat does to some extend

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iutin picture iutin  ·  4Comments

jvandenaardweg picture jvandenaardweg  ·  4Comments

chetstone picture chetstone  ·  4Comments

coldfins picture coldfins  ·  3Comments

MacMillan13 picture MacMillan13  ·  3Comments