React-native-iap: PurchaUpdatedListener вызывается только один раз при запуске приложения и никогда не вызывает после вызова requestSubscription

Созданный на 21 апр. 2020  ·  22Комментарии  ·  Источник: dooboolab/react-native-iap

Версия react-native-iap

4.4.6

Версия react-native

0,61,5

Платформы, на которых вы столкнулись с ошибкой (IOS или Android или оба?)

iOS

Ожидаемое поведение

purchaseUpdatedListener requestSubscription вызывается каждый раз после вызова

Фактическое поведение

PurchaUpdatedListener вызывается только один раз при запуске приложения и никогда не вызывает после вызова requestSubscription

Протестированная среда (Эмулятор? Настоящее устройство?)

Настоящее устройство

Шаги по воспроизведению поведения

Просто следуйте readme и попробуйте запросить подписку

📱 iOS 🕵️‍♂️ need more investigation 🙏 help wanted

Самый полезный комментарий

Была та же проблема, что и я не добавил вызов initConnection() .
README, кажется, просто обновлен жирной частью здесь:

initConnection() В iOS он просто вызовет метод canMakePayments и вернет значение __, которое требуется для правильной работы слушателей .__

Я думаю, что эту часть «В iOS он просто вызовет canMakePayments» следует удалить, а также добавить initConnection() в базовый пример.

Я действительно был убежден, что это необязательно, потому что этого не было в примере

Добавление initConnection() перед регистрацией слушателя / ов покупки устранило это для меня, так что это, вероятно, связано с # 1002 и # 756

Все 22 Комментарий

Есть ли у кого-нибудь еще такая же проблема? @Strate вы звонили в finishTransaction ?

@hyochan да, но на самом деле этот вызов происходит после перезапуска приложения

@hyochan Я пробовал пакет expo-in-app-Purchase, и такой проблемы нет - вроде все в порядке

@Strate Я хочу увидеть ваш код. Сам не могу найти ни одной ошибки :(

этот вопрос абсолютно бесит. Есть ли предыдущая версия, в которой это не так?

Есть ли у кого-нибудь еще такая же проблема? @Strate вы звонили в finishTransaction ?

Как это возможно, если покупка является аргументом в finishTransaction? Таким образом, вам нужен прослушиватель событий, чтобы передать аргумент в finishTransaction.

Ожидается, что purchaseUpdatedListener

@hyochan извините, но похоже, что у меня сейчас нет настоящего кода, я переключился на модуль expo-in-app-purchase . Похоже, у @Sophrinix такая же проблема.

Кстати, в моем коде не было ничего особенного: зарегистрируйте слушателя, как только приложение запустится, и просто следуйте readme.

Оказывается, это регресс.

Если вы используете следующие версии, то все работает:

"react": "16.8.1",
"react-native": "^0.59.10",
"react-native-iap": "4.3.0",

Проблема возникает, когда вы пытаетесь использовать react-native-iap 4.4.4 и версию react-native до 0.60

@Sophrinix Я только что попробовал requestPurchase на своей стороне, и все вроде работает. Не могли бы вы поделиться своим кодом?

Также проверьте еще раз, звонили ли вы на initConnection . Это важные изменения в недавнем обновлении, которые теперь необходимо вызывать в iOS как в android .

Я подтверждаю, что возврат к 4.3.0 работает. Я сходил с ума с последней версией, я отлаживал более 1 часа, пытаясь найти проблему.

Если я могу добавить, от 4.3.4 до 4.4.3 работает нормально, проблема начинается в 4.4.4

Если я могу добавить, от 4.3.4 до 4.4.3 работает нормально, проблема начинается в 4.4.4

То же самое здесь, понижен с 4.4.8 до 4.4.3, и теперь он работает!

Есть ли у кого-нибудь еще такая же проблема? @Strate вы звонили в finishTransaction ?

У меня такая же проблема с 4.4.0 - ни один из прослушивателей событий не вызывается, включая purchaseErrorSubscription .

Просто прочтите о понижении версии, я собираюсь попробовать это ...

Изменить: это серьезная проблема, потому что:

  • предотвращает отправку покупок на серверную обработку
  • он предотвращает откат состояния, когда кто-то отменяет покупку.

Я также могу подтвердить, что 4.3.0 работает.

У меня была такая же проблема в течение нескольких дней с RN 0.62.2 и react-native-iap 4.4.8
Я как-то пропустил initConnection() вероятно, потому, что он отсутствует в примере в README

Была такая же проблема на iOS при обновлении до 4.4.8, из-за которой некоторые подписки не были завершены. Переход на 4.4.3 на данный момент решил проблему. Обязателен ли initConnection ()? Документ делает вид, будто это не так

Была та же проблема, что и я не добавил вызов initConnection() .
README, кажется, просто обновлен жирной частью здесь:

initConnection() В iOS он просто вызовет метод canMakePayments и вернет значение __, которое требуется для правильной работы слушателей .__

Я думаю, что эту часть «В iOS он просто вызовет canMakePayments» следует удалить, а также добавить initConnection() в базовый пример.

Я действительно был убежден, что это необязательно, потому что этого не было в примере

Добавление initConnection() перед регистрацией слушателя / ов покупки устранило это для меня, так что это, вероятно, связано с # 1002 и # 756

Я использую 4.4.9, и проблема, описанная в этой заявке, также возникает у меня.
Слушатель вызывается только при запуске, но если я устанавливаю его, а затем выполняю покупку, он не вызывается.
Я решил это, подписавшись на собственное событие напрямую, посмотрев на react-native-iap/index.ts и выяснив, что происходит внутри.
Это можно сделать в любое время и будет продолжаться. (Просто убедитесь, что это сделано только один раз)

import { NativeModules, NativeEventEmitter } from 'react-native';
import { Observable } from 'rxjs/Observable';

const purchaseEvent = Observable.fromEvent(
  new NativeEventEmitter(NativeModules.RNIapIos),
  'purchase-updated'
);
const purchaseSubscription = purchaseEvent.subscribe((transactionData) => {
  // Trigger server receipt validation here...
});
const errorEvent = Observable.fromEvent(
  new NativeEventEmitter(NativeModules.RNIapIos),
  'purchase-error'
);
const errorSubscription = errorEvent.subscribe((errorData) => {
  // Handle errors here...
});

Многие люди сталкиваются с ошибками, потому что initConnection() отсутствует в примере кода README. Я добавил его сюда: # 1088, но если бы кто-нибудь мог дважды проверить мой код, был бы признателен. (У меня все еще не работает мой код, поэтому я не слишком уверен в этом ...)

Я также столкнулся с этой проблемой в версии 5.1.1. initConnection не решил. Обратные вызовы слушателя никогда не запускаются при покупкеUpdate. Хотя на android работает нормально. Мое обходное решение заключалось в использовании Observables, как это сделал

import React, { useContext, useEffect, useState } from 'react';
import { Alert, EmitterSubscription, Platform, NativeEventEmitter,
    NativeModules } from 'react-native';
import { connect } from 'react-redux';
import RNIap, {
    InAppPurchase,
    PurchaseError,
    SubscriptionPurchase,
    purchaseErrorListener,
    purchaseUpdatedListener,
} from 'react-native-iap';
import { Observable, Subscription } from 'rxjs';

const RNIAPEvent = new NativeEventEmitter(NativeModules.RNIapIos);
const purchaseObservable = new Observable((subscriber) => {
    RNIAPEvent.addListener('purchase-updated', (event) => {
        subscriber.next(event);
    })
})

const RNIAPErrorEvent = new NativeEventEmitter(NativeModules.RNIapIos);
const purchaseErrorObservable = new Observable((subscriber) => {
    RNIAPErrorEvent.addListener('purchase-error', (event) => {
        subscriber.next(event);
    })
})


const Wrapper = ({ ...props }) => {

    let purchaseUpdateSubscription: EmitterSubscription | Subscription | null = null;
    let purchaseErrorSubscription: EmitterSubscription | Subscription | null = null;

    const validateTransaction = async (purchase: SubscriptionPurchase) => {    
        return new Promise(async (resolve) => {
              //resolve(validationResponseFromYourBackend)
        }
    }

    const handleSubEvent = async (purchase: InAppPurchase | SubscriptionPurchase) => {
        const receipt = purchase.transactionReceipt;
        const purchaseToken = purchase.purchaseToken
        if (receipt) {
            try {
                const result = await validateTransaction(purchase);
                if (result.status === 200) {
                    RNIap.acknowledgePurchaseAndroid(purchaseToken).then(() => {
                        RNIap.finishTransaction(purchase, false)
                        .then(() => giveYourUserValue())
                        .catch((e) => {
                            //
                        })
                    })
                }
            } catch (err) {
                //
            }
        }
    }


    useEffect(() => {
        RNIap.initConnection()
            .then(() => {
                RNIap.flushFailedPurchasesCachedAsPendingAndroid().catch(() => {
                    // exception
                    })
                .then(() => {
                    if (Platform.OS === 'ios') {
                        //Documented implementation has issues purchaseUpdatedListener callback
                        purchaseUpdateSubscription = purchaseObservable.subscribe((purchase) => {
                            console.log('purchase observable', purchase)
                            handleSubEvent(purchase);
                        });

                        purchaseErrorSubscription = purchaseErrorObservable.subscribe((error) => {
                            console.log('purchaseErrorListener', error);
                        })

                    } else {
                        //for android use the documented method. Callbacks work.
                        purchaseUpdateSubscription = purchaseUpdatedListener(
                            (purchase: InAppPurchase | SubscriptionPurchase) => {
                                handleSubEvent(purchase);
                            }

                        );
                        purchaseErrorSubscription = purchaseErrorListener(
                            (error: PurchaseError) => {
                               console.log('purchaseErrorListener', error);
                            },
                        );
                    }

                })
            })
        return () => {
              // clear your listeners
             //eg if Subscription purchaseErrorSubscription.unsubscribe() 
            //eg if EmitterSubscription purchaseErrorSubscription.remove() 
        }
    }, []);

    return (
        <InAppSubContext.Provider
            value={{
                someValueYouWantPassedDown: 'theValue'
            }}
        >
            {props.children}
        </InAppSubContext.Provider>
    )
}

const mapState = (state) => ({ someProps: 'yeah' });

const InAppSubscriptionManager = connect(mapState)(Wrapper);

export default InAppSubscriptionManager;

Теперь вы можете использовать это, чтобы обернуть свое приложение в App.tsx :


import InAppSubscriptionManager from './path/to/inAppSubscriptionManager';
const App = () => {

    return (
        <Provider store={store}>
                <InAppSubscriptionManager>

                    <AppNavigator />

                </InAppSubscriptionManager>
        </Provider>
    );
}

export default App;

Рад, что помог. У нас это в производстве с июня.
В какой-то момент он действительно изменился с Observable на это (мы не используем машинописный текст)

      const purchaseEvent = new NativeEventEmitter(NativeModules.RNIapIos);
      const subscription = purchaseEvent.addListener(
        'purchase-updated',
        transactionData => {
          console.log('IAP-LOG purchase-updated');
          dispatch(validateRecepit(transactionData));
        }
      );
      const errorSubscription = purchaseEvent.addListener(
        'purchase-error',
        data => {
          crashlytics().log(`Purchase error ${JSON.stringify(data)}`);
          console.log('IAP-LOG purchase-error', data);
        }
      );
    };
Была ли эта страница полезной?
0 / 5 - 0 рейтинги