React-native-iap: purchaseUpdatedListener se llama repetidamente

Creado en 3 feb. 2020  ·  6Comentarios  ·  Fuente: dooboolab/react-native-iap

Versión de react-native-iap

4.3.0

Versión de react-native

0,60,5

Plataformas a las que se enfrentó el error (¿IOS o Android o ambos?)

Ambos

Comportamiento esperado

Siguiendo el ejemplo, quiero llamar a un método personalizado después de que se haya comprado mi suscripción. ¿Tengo entendido que después de reconocer la compra, el oyente debe ser eliminado? Intenté llamar explícitamente a remove pero no tuve éxito.

Ejemplo

 const purchaseListener = purchaseUpdatedListener(purchase => {
      const receipt = purchase.transactionReceipt;
      if (receipt) {
        callCustomEndpoint().then(result => {
          if(result){
            // Subscription is valid
            finishTransaction(purchase);
          }
        }) 
      };
      finishTransaction(purchase);
    });

Comportamiento real

El método callCustomEndpoint () se llama varias veces. ¿Cómo puedo evitar que esto suceda? Como solo necesito llegar a este punto final una vez.

Estoy usando un componente funcional en lugar de un componente de clase si es importante.

Entorno probado (¿Emulador? ¿Dispositivo real?)

Dispositivo real

Pasos para reproducir el comportamiento

🙏 help wanted

Comentario más útil

Voy a dejar mi solución para ganchos para aquellos que la necesitarán más adelante.

fuera de su componente de estado (aunque probablemente también funcione dentro):

var purchaseUpdateSubscription;
var purchaseErrorSubscription;
const loadIAPListeners = () => {
  initConnection(); // important, or else it won't trigger before a random state change
  purchaseUpdateSubscription = purchaseUpdatedListener(
    async (
      purchase: InAppPurchase | SubscriptionPurchase | ProductPurchase,
    ) => {
      console.log('purchaseUpdatedListener', purchase);
      let receipt = purchase.transactionReceipt;
      if (receipt) {
        apis.checkreceipt({data: purchase, platform: Platform.OS}); // I personally don't care about callback
        if (Platform.OS === 'ios') {
          await RNIap.finishTransactionIOS(purchase.transactionId);
        } else if (Platform.OS === 'android') {
          await RNIap.acknowledgePurchaseAndroid(purchase.purchaseToken);
        }
        await RNIap.finishTransaction(purchase, true);
        await RNIap.finishTransaction(purchase, false);
      } else {
        // Retry / conclude the purchase is fraudulent, etc...
      }
    },
  );
  purchaseErrorSubscription = purchaseErrorListener((error: PurchaseError) => {
    console.log('purchaseErrorListener', error);
  });
};

dentro de su componente de estado:

useEffect(() => {
    loadIAPListeners();
    return () => {
      purchaseUpdateSubscription.remove();
      purchaseErrorSubscription.remove();
    };
  }, []);

Todos 6 comentarios

Sospecho que ha registrado purchaseListener varias veces cuando se reproducen componentes.

Gracias, desde entonces he reescrito esto usando ganchos para que no se llame en cada render. Mi error fue intentar tomar el ejemplo proporcionado en los documentos de un componente de clase y portarlo a un componente funcional. ¡Buen trabajo en la biblioteca!

@cgathergood Yo también tengo este problema. ¿Te importaría publicar tu código de controlador de eventos usando react hooks?

@cgathergood también me gustaría ver un ejemplo de código. Estoy un poco luchando con los ganchos.

@ wootwoot1234 @osmantuna ¿Puede proporcionar los códigos del controlador de eventos si logró solucionarlo?

Voy a dejar mi solución para ganchos para aquellos que la necesitarán más adelante.

fuera de su componente de estado (aunque probablemente también funcione dentro):

var purchaseUpdateSubscription;
var purchaseErrorSubscription;
const loadIAPListeners = () => {
  initConnection(); // important, or else it won't trigger before a random state change
  purchaseUpdateSubscription = purchaseUpdatedListener(
    async (
      purchase: InAppPurchase | SubscriptionPurchase | ProductPurchase,
    ) => {
      console.log('purchaseUpdatedListener', purchase);
      let receipt = purchase.transactionReceipt;
      if (receipt) {
        apis.checkreceipt({data: purchase, platform: Platform.OS}); // I personally don't care about callback
        if (Platform.OS === 'ios') {
          await RNIap.finishTransactionIOS(purchase.transactionId);
        } else if (Platform.OS === 'android') {
          await RNIap.acknowledgePurchaseAndroid(purchase.purchaseToken);
        }
        await RNIap.finishTransaction(purchase, true);
        await RNIap.finishTransaction(purchase, false);
      } else {
        // Retry / conclude the purchase is fraudulent, etc...
      }
    },
  );
  purchaseErrorSubscription = purchaseErrorListener((error: PurchaseError) => {
    console.log('purchaseErrorListener', error);
  });
};

dentro de su componente de estado:

useEffect(() => {
    loadIAPListeners();
    return () => {
      purchaseUpdateSubscription.remove();
      purchaseErrorSubscription.remove();
    };
  }, []);
¿Fue útil esta página
0 / 5 - 0 calificaciones