React-native-iap: Não é possível obter variedade de produtos / assinaturas

Criado em 19 ago. 2019  ·  31Comentários  ·  Fonte: dooboolab/react-native-iap

Versão do react-native-iap

3.3.9

Versão do react-native

0,59,9

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

iOS e Android

Comportamento esperado

Espero poder obter uma variedade de produtos e assinaturas criadas no Play console e na Appstore.

Comportamento real

As funções RNIap.getProducts e RNIap.getSubscriptions sempre retornam arrays vazios.

Ambiente testado (emulador? Dispositivo real?)

Simulador iOS, emulador Android e dispositivo real Android

Passos para reproduzir o comportamento

  1. Adicionar produtos no Google Play Console e Apple Appstore Connect
  2. Eu usei o código da pasta de exemplo
  3. Eu mudei ids de produtos / assinaturas

Esperei mais de 24 horas. Eu também criei versões Internas e Alfa no Google Play Console, mas ainda recebo apenas matrizes vazias de volta.

Acho que não estou certo de quando exatamente devo esperar que ele comece a funcionar. Por exemplo, quando minha implementação de teste Alpha ainda está com publicação pendente no Google Play Console, isso significa que react-native-iap não funcionará? Tenho que esperar até que o aplicativo seja publicado para testá-lo?

Também sei que não poderei fazer nem mesmo compras de teste no simulador / emulador, mas getProducts / getSubscriptions funcionar em emuladores ou preciso de um dispositivo real para testá-lo?

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>
        );
    }
}
📱 iOS 🙏 help wanted 🚶🏻 stale 🤖 android

Comentários muito úteis

Claro. Depois de publicado pela google play store, irei confirmar aqui

ATUALIZAR

Depois que meu aplicativo foi publicado na Google Play Store, as compras surgiram e funcionaram. Demora 3 dias para aprovar. Obrigado a @jvandenaardweg

ATUALIZAÇÃO 2

react-native-iap pode funcionar no emulador de Android, se o emulador tiver suporte para Google Play Store

Todos 31 comentários

Você não precisa de real device para testar em ios para getProducts / getSubscription mas não em android . Por android você precisa ter um dispositivo real para comprar.

Para o Google, consulte meu guia para resolver seu problema.
Na verdade, você não precisa publicar o aplicativo na Playstore para teste, mas precisa fazer o upload do apk assinado.

Eu também tenho esse problema, já criei um produto na apple e não consigo acessá-lo.

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

RNIap.getProducts(itemSkus).then((products) => {
      console.log(products);  //<< returns empty array
}).catch((error) => console.log(error))

Leva tempo para que o produto reflita em sua experiência?

Acordos, fiscais e bancários estão todos ativos
"react-native-iap": "^ 3.4.0",
E o in-app já está com o status "Pronto para enviar"

@nateblog que tipo de produto você criou? Uma assinatura ou outra coisa?

Além disso, você adicionou uma localização no App Store Connect para seu produto / assinatura? Nesse caso, tente adicionar a localização que você tem ativo em seu dispositivo ou simulador. Lembro que tive alguns problemas com isso antes. Meu simulador e local do dispositivo estão em inglês, então adicionei apenas a localização "Inglês (EUA)" para minhas assinaturas.

@jvandenaardweg - obrigado pela resposta, sim, já adicionei a localização, pois o status do aplicativo não será definido como "Pronto para enviar" se eu pular a localização. Defino a localização para "Inglês (EUA)", pois o dispositivo que estou usando está usando o inglês e sim, o produto é assinatura.

ATUALIZAR

Já me certifiquei de que habilitei os recursos do aplicativo e fiz o downgrade do pacote para 2.4.0, mas ainda com o mesmo resultado. . Não consigo obter os produtos, ele apenas retorna uma matriz vazia.

Também vinculei o pacote manualmente já que outros posts sugeriram não usar o link react-native, mas ainda o mesmo resultado. Estou usando o simulador e o dispositivo real.

Desculpe, está resolvido agora, o problema era o id do pacote no meu xcode, estou usando o id do pacote errado, tudo funciona agora

Tive um parecido, e só precisava fazer o processo de linkagem da biblioteca manualmente. (ios)

Estou tendo o mesmo problema, não estou carregando nenhum produto do Itunes Connect e não tenho certeza por onde começar a procurar um problema. O aplicativo está usando uma versão antiga do RN: 0.43.4. Tentei as versões 3.3.7 e 2.5.5 do RN-IAP. Devo usar uma versão mais antiga da biblioteca porque estou em uma versão antiga do React-Native?

Parece um problema difícil de solucionar, pois não há mensagens de erro, apenas dados.

Desculpe, está resolvido agora, o problema era o id do pacote no meu xcode, estou usando o id do pacote errado, tudo funciona agora

Ei, @nateblog! Estou enfrentando um problema semelhante: recebo matrizes vazias para produtos e assinaturas e criei 2 itens de assinatura no App Store Connect. Você poderia explicar o que havia de errado com o id do pacote? Não acho que estou enviando os SKUs de item corretos porque não consegui encontrar nenhuma referência sobre como eles são construídos ou o que são - eles são [Identificador de pacote]. [ProductId do item de compra] ou apenas [ProductId do item de compra]?

Além disso, gostaria de acrescentar que tenho identificadores de pacote ligeiramente diferentes para meus esquemas de liberação e depuração:

  • Release - 'domain.appName';
  • Depurar - 'domain.appName.dev';
    Os itens de compra no aplicativo que criei estão relacionados à versão de produção (ou seja, lançamento) do aplicativo. Isso significa que não consegui acessar esses itens da versão dev do aplicativo?

Qualquer conselho seria muito apreciado.

Tive um parecido, e só precisava fazer o processo de linkagem da biblioteca manualmente. (ios)

Você salvou meu dia!

Eu integrei o react-native-iap e carreguei meu apk assinado para a versão beta na play store e também adicionei um plano de assinatura. Estou tentando obter a lista de assinatura por ID de assinatura no modo de depuração, que sempre retorna uma matriz vazia. Posso realmente testar a assinatura no modo de depuração?

@ShridharCodewave estou enfrentando o mesmo problema. por favor, deixe-me saber se você pode resolver o problema :(

react-native-iap: 3.3.2

Estou enfrentando o mesmo problema no Android Emulator. Eu carreguei o apk no Google Play Store para o canal beta e adicionei produtos.

image

Primeiro, o init de conexão, então estou tentando buscar produtos, mas nada aparece no console.warn
Sem resultados aqui
Sem erros aqui

@ismetsezer todo o faturamento In App para Android não funcionará no emulador:

Você não pode usar o emulador para testar o Google Play Billing; você deve instalar seu aplicativo em um dispositivo para testar o Google Play Faturamento.
https://developer.android.com/google/play/billing/billing_testing

Você precisa de um dispositivo real para isso.

No iOS, você pode buscar dados de assinatura no simulador. Mas você não pode comprar, para isso também precisa de um aparelho de verdade.

Para os outros comentários acima: Certifique-se também de que versionName e versionCode em android/app/build.gradle são iguais ou superiores aos carregados no Google Play Console.

Você também precisa de um aplicativo revisado ativo em uma faixa de não produção, devido à nova política de revisão do Android:

Anteriormente, você poderia testar um aplicativo enviando uma versão de "rascunho" não publicada. Esta funcionalidade não é mais compatível. Em vez disso, você deve publicar seu aplicativo na faixa de teste fechada ou aberta. Para obter mais informações, consulte Os aplicativos de rascunho não são mais suportados.
https://developer.android.com/google/play/billing/billing_testing

"Publicar" em uma faixa de teste fechada / aberta significa que ela precisa passar pelo novo processo de revisão do Google Play. O que pode levar alguns dias para novos aplicativos e apenas algumas horas para aplicativos existentes.

Não sei exatamente os passos que fiz, mas para mim está trabalhando localmente com um dispositivo Android. Portanto, provavelmente não é um problema de pacote react-native-iap, mas mais uma questão de configuração.

Se alguém puder confirmar o acima, talvez seja bom atualizar o README sobre essa mudança. Como isso é algo novo desde o mês passado.

Obrigado @jvandenaardweg quando mudei para o dispositivo real, Sim, funciona e a conexão é bem-sucedida, mas como você disse e de acordo com o link, tenho que esperar que o aplicativo de teste seja publicado no Canal Beta porque a matriz de produtos está vazia

Bom saber @ismetsezer . Você pode confirmar se ele começa a funcionar para você com um aplicativo de teste revisado / publicado? Porque então podemos atualizar o leia-me com essas novas informações :-)

Claro. Depois de publicado pela google play store, irei confirmar aqui

ATUALIZAR

Depois que meu aplicativo foi publicado na Google Play Store, as compras surgiram e funcionaram. Demora 3 dias para aprovar. Obrigado a @jvandenaardweg

ATUALIZAÇÃO 2

react-native-iap pode funcionar no emulador de Android, se o emulador tiver suporte para Google Play Store

@kesepara Tive que esperar algumas horas após adicionar o novo plano de assinatura na Play Store para que ele aparecesse no dispositivo.

Olá @ismetsezer e @kesepara ,
Eu realmente apreciaria sua contribuição sobre o fluxo de desenvolvimento, pois algo ainda não está claro para mim.
Configurei o RN IAP para iOS e está funcionando bem agora.
Agora estou começando a fazer parte Android, e eu encontrei aqui que temos que usar assinado APK carregado na pista fechada (pelo menos) para ser capaz de características de pagamento de teste.
Mas em seus comentários você está dizendo que conseguiu testá-lo no emulador do Android, correto?
Além disso, se tivermos que usar o APK assinado na loja, como podemos depurar?
Sua ajuda seria muito apreciada.

Olá @beeremy, obrigado por suas boas opiniões. Você tem que testar o iap em um dispositivo real ou emulador que tenha suporte do Google Play para buscar produtos. O IAP funcionou depois que publiquei o aplicativo na Google Play Store, isso pode ser alterado, mas pelo menos você tem que fazer o upload ou dar um rascunho na loja para testar esse recurso. Mas leva de 2 a 3 horas para funcionar.

Olá @ismetsezer , obrigado pelo seu feedback.

Para quem pode ser útil, consegui fazer uma configuração de depuração em execução após seguir esta recomendação: https://stackoverflow.com/questions/36113347/is-it-possible-to-debug-locally-google-plays -in-app-billing-in-android-studio

Posso confirmar, como @ismetsezer, que as assinaturas e os produtos funcionarão no Android depois que o aplicativo for publicado no console do Google Play. Tentar obter assinaturas / produtos quando o aplicativo ainda não foi publicado não funcionará no Android.

No iOS, as assinaturas e os produtos funcionam sem que o aplicativo seja publicado.

Olá, parece que não houve nenhuma atividade sobre este problema recentemente. O problema foi corrigido ou ainda requer a atenção da comunidade? Este problema pode ser resolvido se nenhuma outra atividade ocorrer. Você também pode rotular esse problema como "Para discussão" ou "Bom primeiro problema" e eu o deixarei em aberto. Obrigado por suas contribuições.

RN 0.59.1 no Android dev aqui e estou usando iap versão 4.4.1

Minha construção está atualmente na trilha Alpha. Depois , reconstruí como de costume em minha máquina no modo de depuração, em Platform.select ({}), especifiquei o ID da assinatura como está no Play Console e chamei getSubscriptions (), mas estou recebendo uma matriz vazia. É porque está em Alpha? Alguma ideia?

@edgaralienfoe , você ativou sua assinatura no Google Play Console?

@acostalima deve ser ativado. Achei que talvez demore alguns dias para isso acontecer, mas ainda não tive sorte.

@edgaralienfoe Estou perguntando porque lembro que há uma opção para ativar explicitamente uma assinatura no Google Play Console e, se não estiver ativa, a assinatura não aparecerá em seu aplicativo. Mas, se você diz, pode haver algum outro problema então.

@edgaralienfoe Você encontrou a solução? Talvez a versão do seu aplicativo precise ser superior à da faixa Alfa

@edgaralienfoe Você encontrou a solução? Talvez a versão do seu aplicativo precise ser superior à da faixa Alfa

A trilha Alpha funciona bem. Venho testando IAPs há algum tempo com compilações implantadas no Alpha sem problemas. A faixa interna, por outro lado, não funciona.

Para todos que podem ter problemas aqui, o que funcionou no iOS para mim foi vincular o projeto manualmente, conforme sugerido por @ Kuhne1 - funcionou depois de limpar a pasta de compilação e instalar pods manualmente, espero que seja útil para qualquer pessoa!

Olá, parece que não houve nenhuma atividade sobre este problema recentemente. O problema foi corrigido ou ainda requer a atenção da comunidade? Este problema pode ser resolvido se nenhuma outra atividade ocorrer. Você também pode rotular esse problema como "Para discussão" ou "Bom primeiro problema" e eu o deixarei em aberto. Obrigado por suas contribuições.

Encerrando este problema após um período prolongado de inatividade. Se esse problema ainda estiver presente na versão mais recente, sinta-se à vontade para criar um novo problema com informações atualizadas.

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