React-native-iap: RNIap.getLes produits ne sont pas prometteurs sur iOS

Créé le 19 déc. 2018  ·  24Commentaires  ·  Source: dooboolab/react-native-iap

Version de react-native-iap

"react-native-iap": "^ 2,3,25"

Version de react-native

"natif réactif": "0,57,4",

Plateformes sur lesquelles vous avez rencontré l'erreur (IOS ou Android ou les deux?)

IOS

Comportement attendu

buyProduct doit retourner la promesse (.then () n'est pas appelé),

Comportement réel

buyProduct ne renvoyant aucune promesse, dans Android, il fonctionne bien, .then () appelle avec succès, mais dans iOS ce n'est pas le cas.

Environnement testé (émulateur? Real Device?)

Appareil réel

Étapes pour reproduire le comportement

onBuyNowPress() {
    this.setState({ loading: true });
    RNIap.getProducts(['product_id']).then(success => { 
       RNIap.buyProduct('product_id').then(purchase => { 
        console.log("Purchase >>", purchase)
        this.setState({
          loading: false,
          receipt: purchase.transactionReceipt, 
        });
        Alert.alert('Purchase Successful!');
        this.props.getPurchase();
       }).catch(err => { 
         console.log(err.code, err.message);
          this.setState({ loading: false });
          Alert.alert(err.message);
          if(err.message === "You already own this item.") {
            this.props.getPurchase();
          }
        }) 
      }).catch(error => { 
        alert(error); 
        this.setState({ loading: false });
      })
  }

Dans iOS, j'achète déjà un produit, donc encore une fois lorsque j'appuie sur acheter maintenant, je reçois une fenêtre contextuelle comme si vous achetiez déjà ce produit. mais .then () ou .catch () ne reçoivent pas d'appel.

J'ai aussi essayé la méthode getAvailablePurchases (), elle retourne toujours []

📱 iOS 🙏 help wanted

Commentaire le plus utile

Pouvez-vous essayer 2.4.0-beta4 ?

Tous les 24 commentaires

@LinusU Je pense que @JJMoon avait raison. J'ai supprimé tous les async et le problème se reproduit. Qu'est-ce que tu penses? @ ZeroCool00 Souhaitez-vous passer à 2.3.24 pour le moment?

@ ZeroCool00 En fait, pourriez-vous essayer 2.3.26 pour nous?

@hyochan je vais tester bientôt .. et vous le faire savoir, et merci pour la réponse rapide.

@hyochan j'ai essayé avec 2.3.26, ça ne marche pas? Toute solution?

@ ZeroCool00 Alors il doit s'agir d'un problème de liaison. Vous devriez essayer de unlink et de nouveau link .

@hyochan j'ai essayé, même si je dissocie et que je désinstalle et que je réinstalle et que je lie à nouveau. mais ça ne marche toujours pas

@ ZeroCool00 Si vous êtes dans la fenêtre, le script de lien natif de réaction est encore plus instable. Avez-vous essayé manuellement? Veuillez également essayer 2.3.24 . Je pense que vous rencontrez un problème de configuration.

@hyochan im sur mac, et je dissocie et que désinstaller puis installer 2.3.24, et faire la configuration manuelle, suivez chaque étape, cela fonctionne avec Android, dans iOS, il ne s'affiche toujours pas. le processus fonctionne bien. im obtenant le popup et le produit obtenant également l'achat, mais aucune promesse de retour.?

existe-t-il une autre configuration pour iOS? Je suis coincé ici, y a-t-il un autre moyen d'obtenir que j'achète déjà.

@JJMoon Pourriez-vous aider @ ZeroCool00 ?

@ ZeroCool00 Essayez également de supprimer Alert et utilisez console pour tester à la place. Parce que ios génère automatiquement des Alert natifs lorsque l'achat est en cours de traitement, ce qui peut interrompre votre code.

@hyochan Plz rouvrir ceci .. j'ai tout essayé .. je supprime également Alert. même j'arrête le débogage et vérifie .. son ne fonctionne tout simplement pas. Je voulais publier mon application, mais je suis coincé ici. j'ai même essayé cette lib https://github.com/chirag04/react-native-in-app-utils

cette bibliothèque a également le même problème. Le processus d'achat fonctionne bien mais n'obtient aucune promesse.

y a-t-il une méthode de cycle de vie où je reçois un rappel d'événement. Je veux juste un rappel d'événement où je peux appeler l'api du serveur.

@ ZeroCool00 Pourriez-vous essayer d'utiliser également async et await ? J'utilise également ceci dans notre application et nous ne sommes pas confrontés à ce problème.

@hyochan pouvez-vous s'il vous plaît fournir votre démo .. comment l'utilisez vous .. ce serait d'une grande aide.

async forIOS() {
    let purchase =  await RNIap.buyProduct('product_id');
    console.log("BannerPurchase >>",purchase);  **<--- THIS IS NOT GETTING CALL**
    if(purchase) {
      console.log("Purchase >>", purchase)
      this.props.getPurchase();
      this.setState({
        loading: false,
        receipt: purchase.transactionReceipt, 
      });
      console.log('Purchase succesfully')
    }
  }

@hyochan je suis ce que vous dites, il semble que ce processus soit infini, ne renvoyant rien. je n'ai même pas le journal.

Étant donné que de nombreux autres utilisent nos modules ces jours-ci, votre cas semble assez étrange. Ce serait difficile pour nous de comprendre à moins que nous ayons un code de travail complet de votre part.

@hyochan Ayant le même problème que @ ZeroCool00
Juste mis à jour de 2.3.26 à 2.4.0-beta3 (fait un dissociation et un lien), la même histoire.
Obtenir cela dans les journaux de l'appareil. En utilisant un vrai iPhone, développement construit via xCode (fil connecté).

[IAPInfoManager]: Update operation failed, error: Error Domain=SSErrorDomain Code=109 "Cannot connect to iTunes Store" UserInfo={NSLocalizedDescription=Cannot connect to iTunes Store, SSErrorHTTPStatusCodeKey=401}

Mais des pop-ups avec achat apparaissent, avec une histoire de réussite. Mais aucune réaction dans Javascript Thread là-dessus :(
La promesse n'est pas résolue ou rejetée dans le module iOS.

try {
      let purchase = false;

      console.log('BEFORE BUY');
      if (Platform.OS === 'ios') {
        purchase = await RNIap.buyProduct(selected);
      } else {
        purchase = await RNIap.buySubscription(selected);
      }
      console.log('AFTER BUY');

      await RNIap.finishTransaction();
      console.info('purchase >', purchase);
      setSubscription({type: selected, purchaseData: purchase});
    } catch (err) {
      console.log(err); // TODO add something went wrong
    }

AFTER BUY
Ne se présente même pas. La même histoire sans async / await, avec la résolution de .then promise.

Des idées sur ce qui pourrait causer ce problème?

Pouvez-vous essayer 2.4.0-beta4 ?

@hyochan Merci beaucoup 👍
Problème résolu de mon côté.

@IsaevTimur comment l'avez-vous résolu? son ne fonctionne toujours pas.

@hyochan Voici le code complet de mon module d'achat inapp

import React, { Component } from 'react';
import { View, ImageBackground, TouchableOpacity, Image, Alert, 
  ActivityIndicator, Platform } from 'react-native';
import {inapp, btnBuy, purple} from '../helper/constants';
import ImageResizeMode from 'react-native/Libraries/Image/ImageResizeMode'
import { connect } from 'react-redux';
import { Icon } from 'native-base';
import { Actions } from 'react-native-router-flux';
import * as RNIap from 'react-native-iap';
import { getItems, getPurchase, fetchCategory } from '../action';

const itemSkus = Platform.select({
  ios: [
    'max_asl_unlimited_access'
  ],
  android: [
    'max_asl_unlimited_access'
  ]
});

class Banner extends Component {

  constructor(props){
    super(props);
    this.onBuyNowPress = this.onBuyNowPress.bind(this);
    this.forAndroid = this.forAndroid.bind(this);
    this.forIOS = this.forIOS.bind(this);
  }

  state = {
    loading: false,
  }

  async componentDidMount() {
    try {
      const result = await RNIap.initConnection();
      console.log('result', result);
      this.props.getItems();
    } catch (err) {
      console.warn(err.code, err.message);
    }
}

  componentDidUpdate(prevProps) {
    if(prevProps.purchase !== this.props.purchase) {
      this.props.fetchCategory();
    } 
  }

  onBuyNowPress() {
    this.setState({ loading: true });
    RNIap.getProducts(itemSkus).then(success => { 
      if(Platform.OS == "ios") {
        this.forIOS()
      } else {
        this.forAndroid()
      }
    }).catch(error => { 
      alert(error); 
      this.setState({ loading: false });
    })
  }

  async forIOS() {
    console.log('BannerCall');
    try {
      const purchase = await RNIap.buyProduct('max_asl_unlimited_access');
      console.log("BannerPurchase >>",purchase);
      if(purchase) {
        this.props.getPurchase();
        this.setState({
          loading: false,
        });
        console.log('Purchase succesfully')
      }
    } catch (err) {
      console.log("BannerError >> ", err);
    }
  }

  forAndroid() {
    RNIap.buyProduct('max_asl_unlimited_access').then(purchase => { 
      this.props.getPurchase();
      this.setState({
        loading: false,
        receipt: purchase.transactionReceipt, 
      });
      console.log('Purchase succesfully')
      Alert.alert("Purchase succesfully")
     }).catch(err => { 
       console.log(err.code, err.message);
        this.setState({ loading: false });
        if(err.message === "You already own this item.") {
          this.props.getPurchase();
          Alert.alert("You already own this product, we are restoring your purchase.")
        }
      }) 
  }

  componentWillUnmount() {
    RNIap.endConnection();
  }

  renderSpinner() {
    if(this.state.loading) {
      return (
        <ActivityIndicator size="large" color="#F7CD52" />
      )
    }
    return null
}

  render() {
    const { container, bannerStyle, btnContainer, iconClose } = styles;
    return (
      <View style={container}>
          <ImageBackground source={inapp} style={bannerStyle} resizeMode={ImageResizeMode.contain}>
              <Icon name="close" style={iconClose} type="FontAwesome" onPress={() => {Actions.pop()}}/>
              <View style={btnContainer}>
                {this.renderSpinner()}
                <TouchableOpacity onPress={() => this.onBuyNowPress()}>
                    <Image source={btnBuy}  />
                </TouchableOpacity>
              </View>
          </ImageBackground>
      </View>
    );
  }
}


const styles = {
  container: {
    flex: 1,  
  },
  iconClose: {
    color: '#FFF',
    fontSize: 30,
    alignSelf: 'flex-end',
    margin: 20,
    fontWeight: 'bold',
  },
  bannerStyle: {
    flex: 1,
    width: '100%',
    height: '100%',
    backgroundColor: purple
  }, 
  btnBuy: {
    marginRight: 20,
    marginTop: 160,
    height: 85,
    width: 215,
  },
  btnContainer: {
    flex: 1,
    marginTop: 50,
    justifyContent: 'center',
    alignItems: 'center'
  }
};

function mapStateToProps({ purchase }) {
    return { purchase };
}

export default connect(mapStateToProps, { getItems, getPurchase, fetchCategory })(Banner);

@ ZeroCool00

Assurez-vous que vous utilisez - 2.4.0-beta4.

Assurez-vous également que vous utilisez l'utilisateur SANDBOX (en cours de développement). Qui peut être configuré dans iTunes connect. Ces utilisateurs ont été créés ici - https://appstoreconnect.apple.com/access/users , sous la section Sandbox.

J'espère que cela aide :)

@IsaevTimur
mais mon processus d'achat dans l'App Store fonctionne correctement, ce qui signifie que tout est configuré, et oui, j'utilise 2.4.0-beta4.

voici mon entrée sur le fichier package.json

"react-native-iap": "^2.4.0-beta4",

@hyochan j'ai finalement résolu le problème .. le problème est quand je teste pour la première n'ai pas écrit cette ligne await RNIap.finishTransaction(); dans la méthode .then (). je l'ai ajouté par la suite. c'était le problème, la solution est que j'ai besoin d'effacer la transaction ( await RNIap.clearTransaction(); ), et cela fonctionne.

Merci encore pour votre soutien pour cette superbe bibliothèque.

@ ZeroCool00 Félicitations pour le succès !! Oui, ce genre de problème devrait être mieux résolu de votre côté parce que nous avons besoin d'un peu de réflexion sur ce que vous avez mal fait. Merci d'être de retour pour ceux qui pourraient souffrir de la même chose.

Cette page vous a été utile?
0 / 5 - 0 notes