question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Help with documentation and crash after purchrase

See original GitHub issue

Version of react-native-iap

0.2.16

I’m not an Android or IOs developer and I’m starting now with the purchase system. Among all libraries for react native yours seems the only one with cross platform support and subscription. Thanks for your amazing job.

My questions following:

  1. Is there anything bad in checking the subscription status every time the app loads?

  2. What’s the difference between “refreshAllItems” and “getSubscribeItems”? It seems (from the description) they do the same but in the description is unclear

  3. What’s the difference between buyItem and buySubscriptionItem?

  4. I’m currently testing by releasing alpha version, I tried in many ways to deploy with android a dev version but seems impossible (by design), there’s very little on react native, a guide would be amazing (but I understand you already have done a great job)

  5. The app crash after purchase (the subscription is there after), I don’t see anything wrong and the catch should prevent the app from crashing (but I notice in a few scenario it doesn’t). I’m on Android

  async subscribe() {
    this.log("subscribe called")
    try {
      const isOS = Platform.OS === 'ios'
      const subscriptionName = isOS ? 'com.cooni.monthly' : 'monthly'
      this.log("attempting to subscribe")
      const receipt = await RNIap.buyItem(subscriptionName)
      this.log("receipt")
      this.log(receipt)
    } catch(e) {
      this.log("bought")
      this.log(e)
    }
  }

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:13 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
obsidianartcommented, Mar 5, 2018

so, buySubscribeItem fixed the crash, which is great, and fetchHistory returns the receipt. I still don’t know what “refreshPurchaseItemsAndroid” is for, it’s after the user deleted and reinstalled the app?

0reactions
obsidianartcommented, Mar 7, 2018

My bad, fetchHistory returns an empty array (I had the original receipt in state). That’s my updated code, the purchase works but fetchHistory returns an empty array. I’m not 100% sure I understand the meaning of “refreshing” products, but my understanding is that I should not call it. Thanks for your help

import React, { Component } from 'react'
import { Platform, ToastAndroid, Clipboard, SafeAreaView, ScrollView, Text, TextInput, Image, View, Modal, TouchableOpacity, RefreshControl, Button } from 'react-native'
import Navbar from './Navbar'

import Icon from 'react-native-vector-icons/Entypo'
import I18n from '../i18n'
import * as RNIap from 'react-native-iap';

// Styles
import styles from './Styles/LaunchScreenStyles'

const itemSkus = {
  ios: [
    'com.cooni.monthly',
  ],
  android: [
    'monthly',
  ],
};

async function prepareAndroid() {
  try {
    this.log("1 prepare android")
    const message = await RNIap.prepareAndroid()
    this.log("2 prepare android")
    // Ready to call RNIap.getItems()
  } catch (code) {
    this.log(code)
    // Depending on the situation, Android will have a different error code. Handle accordingly. Visit the link below for current info
    // https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponse.html
    // This catch will never be called on ios
    /*
      -2: FEATURE_NOT_SUPPORTED
      -1: SERVICE_DISCONNECTED
      0: SUCCESS (should never be successful since only errors are caught)
      1: USER_CANCELED
      2: SERVICE_UNAVAILABLE
      3: BILLING_UNAVAILABLE
      4: ITEM_UNAVAILABLE
      5: DEVELOPER_ERROR
      6: ERROR
      7: ITEM_ALREADY_OWNED
      8: ITEM_NOT_OWNED
    */
  }
}

export default class PremiumModal extends Component {
  // copyToClipboard = (text) => {
  //   Clipboard.setString(text)
  //   const isOS = Platform.OS === 'ios'

  //   if (isOS) {
  //     // TODO: https://stackoverflow.com/questions/24893788/android-toast-equivalent-in-ios
  //     alert(I18n.t('donate.copiedToClipboard'))
  //   } else {
  //     ToastAndroid.show(I18n.t('donate.copiedToClipboard'), ToastAndroid.SHORT)
  //   }
  // }

  state = {
    messages: []
  }

  log(msg) {
    this.setState({ messages: [msg, ...this.state.messages] })
  }

  async componentDidMount() {
    this.log("component mount")
    
    try {
      const message = await RNIap.prepareAndroid()
      this.log("messages")
      this.log(message)

      this.log("restore")
      this.restorePreProducts()

      
      const items = await RNIap.getItems(itemSkus)
      this.log("items")
      this.log(JSON.stringify(items))
      this.setState({ items })

      
    } catch (errorCode) {
      this.log("error")
      console.tron.log(errorCode)
    }
  }

  async restorePreProducts() {
    try {
      this.log("restorePreProducts")
      this.log("fetchHistory")
      const subscribed = await RNIap.fetchHistory() // cross platform case
      this.log("subscribed 1")
      if (subscribed) this.log(JSON.stringify(subscribed))
      else this.log(" no subscriptions to restore")
      this.log("subscribed 2")

      // const results = await RNIap.refreshAllItems() // cross platform case
      // let restoredTitles = ""
      // this.log("restore pre products")
      // if (results) this.log(JSON.stringify(results))
      // else this.log(" no products to restore")

      // results.forEach(result => {
      //   this.log(JSON.stringify(result))
      //   if (result.productIdentifier == "com.mywebsite.MyAppPremiumVersion") {
      //     this.setState({ premium: true })
      //     restoredTitles += "Premium Version"
      //   } else if (result.productIdentifier == "com.mywebsite.MyAppRemoveAds") {
      //     this.setState({ ads: false })
      //     restoredTitles += restoredTitles.length > 0 ? "No Ads" : ", No Ads"
      //   }
      // })
      // alert("Restore Successful", "You successfully restored the following purchases: " + restoredTitles)
    } catch (err) {
      this.log(err)
      console.tron.log(err);
      alert(`${err}`);
    }
  }

  async subscribe() {
    this.log("subscribe called")
    try {
      const isOS = Platform.OS === 'ios'
      const subscriptionName = isOS ? 'com.cooni.monthly' : 'monthly'
      this.log("attempting to subscribe")
      const receipt = await RNIap.buySubscribeItem(subscriptionName)
      this.log("receipt")
      this.log(receipt)
    } catch(e) {
      this.log("subscribe error")
      this.log(e)
    }
  }

  render() {
    return (
      <Modal
        visible={this.props.show}
        onRequestClose={this.props.toggle}
        animationType='fade'
        transparent={false}
      >
        <SafeAreaView style={{ flex: 1, backgroundColor: '#0B3954' }}>
          <View style={styles.mainContainer}>
            <View style={{ backgroundColor: '#0B3954', flex: 1 }}>
              <Navbar
                title={I18n.t('menu.premium')}
                rightAction={this.props.toggle}
                rightIcon='cross'
              />

              <ScrollView style={{ flex: 1 }}>
                <View style={{ paddingLeft: 20, paddingRight: 20 }}>
                  <Text style={{ color: '#FFF', fontSize: 16, paddingTop: 10 }}>
                    {I18n.t('premium.l1')}
                  </Text>
                  <Text style={{ color: '#FFF', fontSize: 16, paddingTop: 10 }}>
                    {I18n.t('premium.l2')}
                  </Text>
                  <Text style={{ color: '#FFF', fontSize: 16, paddingTop: 10 }}>
                    {I18n.t('premium.l3')}
                  </Text>

                  <Text style={{ color: '#FFF', fontSize: 16, paddingTop: 10 }}>
                    {I18n.t('premium.l4')}
                  </Text>

                  {this.state.messages.map(el => (
                    <Text style={{ color: '#FFF', fontSize: 16, paddingTop: 10 }}>
                      {JSON.stringify(el)}
                    </Text>
                  ))}

                  <Button
                    onPress={() => this.subscribe()}
                    title={I18n.t('premium.subscribe')}
                    color='#00E500'
                  />

                </View>
              </ScrollView>
            </View>
          </View>
        </SafeAreaView>
      </Modal>
    )
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

CRASHDOCS.org: Welcome
Get Crash Information Instantly. Start a search to find your Accident or Driver Exchange report. Select the State & Agency where the accident...
Read more >
BuyCrash | Home
LexisNexis® BuyCrash is an online solution designed to help consumers, insurance carriers and law enforcement agencies to access, manage or search for police ......
Read more >
Help protect your files in case of a crash - Microsoft Support
Help protect your files in case of a crash · Go to File > Options > Save. · Make sure the Save AutoRecover...
Read more >
Crash reports and records - Texas Department of Transportation
TxDOT is the custodian of crash records for the state of Texas. ... Crash Report (CR-3) by using our Crash Report Online Purchase...
Read more >
Purchase Frequently Asked Questions - Cris Crash Login
A: The Crash Report Online Purchase System is a fast, easy, and secure system designed for individuals involved in motor vehicle traffic crashes...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found