react-native-iap: Cannot get array of products / subscriptions
Version of react-native-iap
3.3.9
Version of react-native
0.59.9
Platforms you faced the error (IOS or Android or both?)
iOS and Android
Expected behavior
I expect to be able to get an array of products and subscriptions created in Play console and Appstore.
Actual behavior
Functions RNIap.getProducts and RNIap.getSubscriptions always return empty arrays.
Tested environment (Emulator? Real Device?)
iOS simulator, Android emulator and Android real device
Steps to reproduce the behavior
- Add products in Google Play Console and Apple Appstore Connect
- I used the code from example folder
- I changed products / subscriptions ids
I did wait for more than 24 hours. I also created Internal and Alpha release in Google Play Console, but I still get only empty arrays back.
I guess I am a bit unclear on when exactly should I expect it to start working. For example when my Alpha testing Roll out is still Pending publication in Google Play Console, does that mean that react-native-iap won’t work? Do I have to wait until the app is published to try it out?
Also I know that I won’t be able to make even test purchases on simulator / emulator, but should getProducts / getSubscriptions work on emulators or do I need real device to test it?
const itemSkus = Platform.select({
ios: ['product_1'],
android: ['1', '2']
});
const itemSubs = Platform.select({
ios: ['subscription_1'],
android: ['subscription_1', 'subscription_2']
});
let purchaseUpdateSubscription;
let purchaseErrorSubscription;
class App extends Component {
constructor(props) {
super(props);
this.state = {
productList: [],
receipt: '',
availableItemsMessage: ''
};
}
async componentDidMount() {
SplashScreen.hide();
try {
const result = await RNIap.initConnection();
await RNIap.consumeAllItemsAndroid();
console.log('result', result);
} catch (err) {
console.warn(err.code, err.message);
}
purchaseUpdateSubscription = purchaseUpdatedListener(async purchase => {
console.log('purchaseUpdatedListener', purchase);
if (purchase.purchaseStateAndroid === 1 && !purchase.isAcknowledgedAndroid) {
try {
const ackResult = await acknowledgePurchaseAndroid(purchase.purchaseToken);
console.log('ackResult', ackResult);
} catch (ackErr) {
console.warn('ackErr', ackErr);
}
}
this.setState({ receipt: purchase.transactionReceipt }, () => this.goNext());
});
purchaseErrorSubscription = purchaseErrorListener(error => {
console.log('purchaseErrorListener', error);
Alert.alert('purchase error', JSON.stringify(error));
});
}
componentWillMount() {
if (purchaseUpdateSubscription) {
purchaseUpdateSubscription.remove();
purchaseUpdateSubscription = null;
}
if (purchaseErrorSubscription) {
purchaseErrorSubscription.remove();
purchaseErrorSubscription = null;
}
}
goNext = () => {
Alert.alert('Receipt', this.state.receipt);
};
getItems = async () => {
try {
const products = await RNIap.getProducts(itemSkus);
console.log('Products', products);
this.setState({ productList: products });
} catch (err) {
console.warn(err.code, err.message);
}
};
getSubscriptions = async () => {
try {
const products = await RNIap.getSubscriptions(itemSubs);
console.log('Products', products);
this.setState({ productList: products });
} catch (err) {
console.warn(err.code, err.message);
}
};
getAvailablePurchases = async () => {
try {
console.info('Get available purchases (non-consumable or unconsumed consumable)');
const purchases = await RNIap.getAvailablePurchases();
console.info('Available purchases :: ', purchases);
if (purchases && purchases.length > 0) {
this.setState({
availableItemsMessage: `Got ${purchases.length} items.`,
receipt: purchases[0].transactionReceipt
});
}
} catch (err) {
console.warn(err.code, err.message);
Alert.alert(err.message);
}
};
requestPurchase = async sku => {
try {
RNIap.requestPurchase(sku);
} catch (err) {
console.warn(err.code, err.message);
}
};
requestSubscription = async sku => {
try {
RNIap.requestSubscription(sku);
} catch (err) {
Alert.alert(err.message);
}
};
render() {
const { productList, receipt, availableItemsMessage } = this.state;
const receipt100 = receipt.substring(0, 100);
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerTxt}>react-native-iap V3</Text>
</View>
<View style={styles.content}>
<ScrollView style={{ alignSelf: 'stretch' }}>
<View style={{ height: 50 }} />
<NativeButton
onPress={this.getAvailablePurchases}
activeOpacity={0.5}
style={styles.btn}
textStyle={styles.txt}
>
Get available purchases
</NativeButton>
<Text style={{ margin: 5, fontSize: 15, alignSelf: 'center' }}>
{availableItemsMessage}
</Text>
<Text style={{ margin: 5, fontSize: 9, alignSelf: 'center' }}>
{receipt100}
</Text>
<NativeButton
onPress={() => this.getItems()}
activeOpacity={0.5}
style={styles.btn}
textStyle={styles.txt}
>
Get Products ({productList.length})
</NativeButton>
{productList.map((product, i) => {
return (
<View
key={i}
style={{
flexDirection: 'column'
}}
>
<Text
style={{
marginTop: 20,
fontSize: 12,
color: 'black',
minHeight: 100,
alignSelf: 'center',
paddingHorizontal: 20
}}
>
{JSON.stringify(product)}
</Text>
<NativeButton
// onPress={() => this.requestPurchase(product.productId)}
onPress={() => this.requestSubscription(product.productId)}
// onPress={() => this.buyItem(product.productId)}
// onPress={() => this.buySubscribeItem(product.productId)}
activeOpacity={0.5}
style={styles.btn}
textStyle={styles.txt}
>
Request purchase for above product
</NativeButton>
</View>
);
})}
</ScrollView>
</View>
</View>
);
}
}
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 34 (4 by maintainers)
Of course.After published by google play store , I will confirm here
UPDATE
UPDATE 2
I have integrated the react-native-iap and uploaded my signed apk to beta release on play store and also added one subscription plan. I am trying to get the list of subscription by subscription ID in debug mode which is always returning an empty array. Can I actually test the subscription in debug mode?
I had a similar, and I just needed to do the linking process of the library manually. (ios)
You don’t need
real deviceto test iniosforgetProducts/getSubscriptionbut not inandroid. Forandroidyou’d need to have real device to purchase.For google, please go over my guide to resolve your issue. You do not actually have to publish the app to playstore for testing but you need to upload the signed apk.
I can confirm as @ismetsezer that subscriptions and products will work in android after app is published in google play console. Trying to get subscriptions / products when app is not yet published will not work for android.
On iOS subscriptions and products are working without having the app published.
Good to hear @ismetsezer . Can you confirm if it starts working for you with a reviewed/published test app? Because then we can update the readme with that new information 😃
Thanks @jvandenaardweg when I switched to real device , Yes It works and connection is successfull but as you said and according to link, I have to wait for test app to published on Beta Channel because products array comes empty
@ismetsezer the whole In App billing for Android won’t work in the emulator:
You need a real device for that.
In iOS you can fetch subscription data in the simulator. But you cannot buy it, for that you also need a real device.
For the other comments above: Also make sure the
versionNameandversionCodeinandroid/app/build.gradleis the same or higher as the one uploaded in Google Play Console.You also need an active reviewed app in a non-production track, because of the new review policy of Android:
“Publishing” in a closed/open testing track means it needs to go through Google Play’s new review process. Which could take a couple of days for new apps, and just a couple of hours for existing apps.
I don’t know the exact steps I did, but for me it’s working locally with an Android device. So it’s probably not a react-native-iap package issue, but more a configuration thing.
If someone can confirm the above, maybe a good thing to update the README about this change. As this is something new since last month.
Hey, @nateblog! I am facing a similar issue: I get empty arrays for products and subscriptions and I have created 2 subscription items within App Store Connect. Could you please elaborate on what was wrong with your bundle id? I don’t think that I am submitting the correct item SKUs because I couldn’t find any reference as to how they are constructed or what they are - are they [Bundle Identifier].[ProductId of the purchase item] or just [ProductId of the purchase item]?
Also, I would like to add that I have slightly different Bundle Identifiers for my release and debug schemes:
Any advice would be greatly appreciated.