React-native-iap: RNIap.getProducts não retornando promessa no ios

Criado em 19 dez. 2018  ·  24Comentários  ·  Fonte: dooboolab/react-native-iap

Versão do react-native-iap

"react-native-iap": "^ 2.3.25"

Versão do react-native

"reagir nativo": "0.57.4",

Plataformas em que você enfrentou o erro (IOS ou Android ou ambos?)

IOS

Comportamento esperado

buyProduct deve retornar a promessa (.then () não é chamada),

Comportamento real

O buyProduct não retorna nenhuma promessa, no Android está funcionando bem, .então () chama com sucesso, mas no iOS não.

Ambiente testado (emulador? Dispositivo real?)

Dispositivo real

Passos para reproduzir o comportamento

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 });
      })
  }

No iOS eu já compro o produto, então, novamente, quando pressiono comprar agora, aparece um popup como se você já tivesse comprado este produto. mas .then () ou .catch () não recebe chamada.

Eu também tentei o método getAvailablePurchases (), sempre retorna []

📱 iOS 🙏 help wanted

Comentários muito úteis

Você poderia tentar 2.4.0-beta4 ?

Todos 24 comentários

@LinusU Acho que @JJMoon estava certo. Eu removi todos os async e o problema surgiu novamente. O que você acha? @ ZeroCool00 Você faria o downgrade para 2.3.24 por enquanto?

@ ZeroCool00 Na verdade, você poderia tentar 2.3.26 para nós?

@hyochan vou testar em breve .. e avisar, e obrigado pela resposta rápida.

@hyochan eu tentei com 2.3.26, não está funcionando? qualquer solução?

@ ZeroCool00 Então deve ser um problema de link. Você deve tentar unlink e recom link novamente.

@hyochan eu tentei, até mesmo desvincular e desinstalar e instalar novamente e vincular novamente. mas ainda não está funcionando

@ ZeroCool00 Se você estiver na janela, o script de link 2.3.24 . Acho que você está enfrentando algum problema de configuração.

@hyochan im no mac, e eu desassocio e desinstalo e instalo 2.3.24, e faço a configuração manual, siga cada passo, funcionando com android, no ios ainda não está aparecendo. o processo está funcionando bem. estou recebendo pop-up e produto também está adquirindo, mas sem retorno de promessa.?

existe alguma outra configuração para ios? estou preso aqui, existe alguma outra maneira de conseguir que eu já compre.

@JJMoon Você poderia ajudar @ ZeroCool00 ?

@ ZeroCool00 Tente também remover Alert e use console para testar. Porque ios gera automaticamente Alert nativos quando a compra está sendo processada, o que pode interromper seu código.

@hyochan Plz reabrir isso .. eu tentei de tudo .. eu também removo o Alerta. até mesmo eu parar de depurar e verificar ... não está funcionando. Eu queria publicar meu aplicativo, mas estou preso aqui. Eu até tentei esta lib https://github.com/chirag04/react-native-in-app-utils

esta lib também tem o mesmo problema .. processo de compra funcionando bem, mas não está recebendo nenhuma promessa.

Existe algum método de ciclo de vida onde recebo o retorno de chamada do evento. Eu só quero o retorno de chamada do evento onde posso chamar a API do servidor.

@ ZeroCool00 Você poderia tentar usar async e await também? Também estou usando isso em nosso aplicativo e não estamos enfrentando esse problema.

@hyochan, você pode fornecer sua demonstração .. como você está usando .. seria uma grande ajuda.

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 sigo o que você fala, parece que esse processo é infinito, não retornando nada. Eu nem mesmo consigo o log.

Como muitos outros usam nossos módulos atualmente, seu caso parece bem estranho. Seria difícil para nós descobrir a menos que tenhamos um código de funcionamento completo seu.

@hyochan Tendo o mesmo problema como @ ZeroCool00
Acabei de atualizar de 2.3.26 para 2.4.0-beta3 (fez uma desvinculação e link), a mesma história.
Obtendo isso nos registros do dispositivo. Usando um iPhone real, construção de desenvolvimento via xCode (fio conectado)

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

Mas aparecem pop-ups com compra, com história de sucesso. Mas nenhuma reação em Javascript Thread sobre ele :(
A promessa não foi resolvida ou rejeitada no módulo 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
Nem mesmo aparece. A mesma história sem async / await, com a resolução de .then promessa.

Alguma ideia do que pode causar este problema?

Você poderia tentar 2.4.0-beta4 ?

@hyochan Muito obrigado 👍
Problema resolvido do meu lado.

@IsaevTimur como você resolveu? ainda não está funcionando.

@hyochan Aqui está o código completo do meu módulo de compra 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

Certifique-se de que está usando - 2.4.0-beta4.

Além disso, certifique-se de que está usando o usuário SANDBOX (em desenvolvimento). Que pode ser configurado no iTunes Connect. Esses usuários criados aqui - https://appstoreconnect.apple.com/access/users , na seção Sandbox.

Espero que ajude :)

@IsaevTimur
mas meu processo de compra na app store está funcionando bem, o que significa que tudo está configurado e, sim, estou usando 2.4.0-beta4.

aqui está minha entrada no arquivo package.json

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

@hyochan eu finalmente resolvi o problema .. problema é quando eu testei pela primeira vez, eu não escrevi esta linha await RNIap.finishTransaction(); no método .then (). eu adicionei depois. esse era o problema, a solução é que preciso limpar a transação ( await RNIap.clearTransaction(); ) e funcionou.

Obrigado novamente por seu apoio n para esta ótima biblioteca.

@ ZeroCool00 Parabéns pelo sucesso !! Sim, esse tipo de problema deve ser resolvido melhor do seu lado, porque precisamos de um pouco de tração sobre o que você fez de errado. Obrigado por voltar para aqueles que podem estar sofrendo na mesma coisa.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

marcosmartinez7 picture marcosmartinez7  ·  61Comentários

the-dut picture the-dut  ·  57Comentários

dayhaysoos picture dayhaysoos  ·  38Comentários

mtakac picture mtakac  ·  31Comentários

curiousdustin picture curiousdustin  ·  30Comentários