"react-native": "0.55.4"
"react-native-iap": "^ 2.3.2"
Androide
Por favor, ayúdame, necesito solucionar este problema de inmediato. Porque ya hay + 2k usuarios
La aplicación se bloquea debido a rniap en muchos dispositivos. En la consola de juegos, vi que este error provoca el bloqueo:
java.lang.RuntimeException:
aquí está el informe de la consola de juego:
https://ibb.co/gDxZQA
No sé qué hacer, usé rniap como en el ejemplo.
en componentDidMount:
tratar {
resultado constante = espera RNIap.initConnection ();
} atrapar (err) {
console.log (err);
}
en componentWillUnmount:
RNIap.endConnection ();
¿Podrías probar nuestra versión reciente 2.3.19
y regresar?
No puedo. Porque fue una situación inmediata. Entonces, cambié el paquete iap. Ahora no hay fallos en + 3000 usuarios. Pero gracias. Lo intentaré en mi próximo proyecto.
Hola, ¿puedes reabrir este problema? Tengo el mismo problema y estoy usando la versión 2.3.21
java.lang.RuntimeException:
en com.facebook.react.bridge.CallbackImpl.invoke (CallbackImpl.java:28)
en com.facebook.react.bridge.PromiseImpl.resolve (PromiseImpl.java:30)
en com.dooboolab.RNIap.RNIapModule $ 4.run (RNIapModule.java:155)
en com.dooboolab.RNIap.RNIapModule $ 3.onBillingSetupFinished (RNIapModule.java:124)
en com.android.billingclient.api.BillingClientImpl $ BillingServiceConnection.onServiceConnected (BillingClientImpl.java:903)
en android.app.LoadedApk $ ServiceDispatcher.doConnected (LoadedApk.java:1658)
en android.app.LoadedApk $ ServiceDispatcher $ RunConnection.run (LoadedApk.java:1687)
en android.os.Handler.handleCallback (Handler.java:789)
en android.os.Handler.dispatchMessage (Handler.java:98)
en android.os.Looper.loop (Looper.java:164)
en android.app.ActivityThread.main (ActivityThread.java:6938)
en java.lang.reflect.Method.invoke (método nativo)
en com.android.internal.os.Zygote $ MethodAndArgsCaller.run (Zygote.java:327)
en com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1374)
este es mi componentDidMount
const itemSKus = Platform.select({
ios: [
...
],
android: [
...
]
});
try {
const message = await RNIap.initConnection();
//console.log(`message = ${message}`);
const items = await RNIap.getProducts(itemSKus);
//console.log(`items = ${items.length}`);
//console.log(items);
this.props.storeInAppPurchaseList(items);
} catch (errorCode) {
console.log(`error rniap = ${errorCode}`);
}
@LinusU ¿Podrías ayudarnos aquí? ¿Por qué callback.run()
bloquea en el lanzamiento? ¿Deberíamos comprobar si callback
es nulo en ensureConnection
? Hm. es un runtime exception
.
Hmmm, ¿qué significa RuntimeException
aquí? ¿No hay más información? @hyochan, ¿por qué crees que callback
era null
? 🤔
@LinusU Gracias por sus comentarios. Actualmente no tengo ni idea. Acabo de ver la línea del problema a continuación.
En RNIapModule.java
línea 124,
callback.run();
¿Tienes alguna idea más?
@LinusU Si no tiene idea de esto, consideraría revertirlo a donde estábamos anteriormente.
Bien, aquí está el problema:
Por alguna razón, llamamos a la devolución de llamada más de una vez, ¡debería ser fácil de solucionar!
@LinusU ¡Se ve genial porque estás en una pista! ¿Podrías darnos un PR
por esto?
¿Por qué hay una RuntimeException en ese método?
if (!mInvoked) {
mJSInstance.invokeCallback(mCallbackId, Arguments.fromJavaArgs(args));
mInvoked = true;
}
¿No es suficiente algo como esto?
@hyochan lo siento, no
@ Ilario17 Probablemente sea para señalar que hay un error lógico en alguna parte, para ser justos, no deberíamos llamar a ese método varias veces
edit: ah, el problema surge cuando onBillingSetupFinished
ocurre más de una vez. En el ensureConnection
necesitamos eliminar el oyente cuando hayamos terminado (es decir, cuando llamamos a callback.run()
o rechazamos la promesa pasada). ¡Debería ser un PR fácil si alguien quiere algo de karma gratis! De lo contrario, intentaré llegar pronto
@LinusU Entonces, ¿te refieres a onBillingSetupFinished
, deberíamos eliminar el billingClientStateListener
? ¿Alguien probaría este para ser parte de nosotros?
Si desea una solución rápida y sucia, agregaría una variable local a esa función, didCallCallback = false
. Luego guarde la llamada a callback.run()
detrás de if (didCallCallback) { didCallCallback = true; callback.run() }
.
Una solución más limpia sería simplemente cancelar el registro del oyente después de la primera llamada por completo ...
Log.d(TAG, "billing client ready");
callback.run();
//deregister the listener here?
Acabo de lanzar 2.4.0-beta2
para corregir esto. Por favor, inténtalo.
@hyochan probaré esta nueva versión
Intente 2.4.0-beta3 ya que beta2 tuvo problemas de regresión.
@hyochan después de la actualización, el error sigue ahí :(
@ Ilario17 ¿Qué hay de 2.4.0-beta5
? Como no puedo reproducir esto en mi lado, necesito tu prueba :(
@hyochan, ¿ @LinusU ?
@ Ilario17 Tenía curiosidad por saber si esa es la solución correcta. Además, creo que onBillingServiceDisconnected
deberían ser notificados. Puede intentar quitarlo y probarlo en su costado y ver si funciona.
No sé si esto está relacionado, pero tengo este bloqueo en 2.4.0-beta5. Es fácil de reproducir en el emulador:
Monto el componente donde se carga IAP, lo desmonto y luego lo vuelvo a montar, boom crash.
EDITAR: Bajé a esta confirmación y ya no se bloquea https://github.com/dooboolab/react-native-iap/commit/2db337ac770a93508507ec046f31085ddbb346fb
Attempt to invoke virtual method 'void com.android.billingclient.api.BillingClient.querySkuDetailsAsync(com.android.billingclient.api.SkuDetailsParams, com.android.billingclient.api.SkuDetailsResponseListener)' on a null object reference
run
RNIapModule.java:223
ensureConnection
RNIapModule.java:113
getItemsByType
RNIapModule.java:218
invoke
Method.java
invoke
JavaMethodWrapper.java:372
invoke
JavaModuleWrapper.java:160
run
NativeRunnable.java
handleCallback
Handler.java:789
dispatchMessage
Handler.java:98
dispatchMessage
MessageQueueThreadHandler.java:29
loop
Looper.java:164
run
MessageQueueThreadImpl.java:192
run
Thread.java:764
Aquí está el código que causa el bloqueo en el segundo montaje (2.4.0-beta5):
componentDidMount() {
this.loadIAPProducts()
}
componentWillUnmount() {
RNIap.endConnection();
}
loadIAPProducts = async () => {
const itemSkus = ['XXXX_id']
const result = await RNIap.initConnection();
if(result) {
try {
const products = await RNIap.getProducts(itemSkus);
if (products) {
this.setState({ iapProducts: products })
}
} catch (err) {
//console.log(err); // standardized err.code and err.message available
}
this.restoreIAPPurchases()
}
}
restoreIAPPurchases = async () => {
try {
const purchases = await RNIap.getAvailablePurchases()
if(purchases) {
purchases.forEach(purchase => {
if (purchase.productId === 'XXXX_id') {
try {
RNIap.consumePurchase(purchase.purchaseToken);
} catch(err) {
}
}
})
}
} catch (err) {
//console.log(err)
}
}
@ rom1k Bueno, esto no funcionaría en el emulador de Android. Inténtelo en un dispositivo real.
@hyochan Noto que la versión 2.4.0-beta3 tiene un 50% menos de fallas, pero aún no es suficiente
Para 2.4.0-beta3 en Android, aparece el error "Error en la compra con el código: 0 (OK)" solo por llamar a getProducts. beta 4 y 5 en realidad hacen que falle. Bajé a 2.3.5 y funciona bien, pero necesito las correcciones de errores del oyente de ios en 2.4.0-beta
''
componentDidMount () {
this.getProductDetails ();
}
getProductDetails = async () => {
try {
await RNIap.initConnection();
const details = await RNIap.getProducts(products);
this.setState({
title: details[0].title,
description: details[0].description,
price: details[0].localizedPrice,
loading: false
});
} catch (err) {
console.log(err.message)
}
};
¿Podrías probar beta5 y comeback? Hubo un error en esa versión, así que arreglé rápidamente
@hyochan @LinusU con la versión 2.4.0-beta5 el error sigue ahí.
Tengo información relevante para esta discusión.
En 2.4.0-beta5, recibo el siguiente error
Attempt to invoke virtual method void com.android.billingclient.api.BillingClient.querySkuDetailsAsync(...) on a null object reference
apuntando a RNIapModule.java
línea 223. Esto implica que mBillingClient
es inesperadamente null
aquí.
Para reproducir : monte un componente react-native que llame a RNIap.getProducts()
en componentDidMount
y RNIap.endConnection()
en componentWillUnmount
. Desmonte el componente y vuelva a montarlo. Debería producirse el error anterior.
La variable clientReady
se usa para rastrear si se ha completado la configuración del cliente de facturación, configurándola en false
en la devolución onBillingServiceDisconnected()
llamada mBillingClient
sí mismo se establece en nulo inmediatamente cuando se llama a endConnection()
. Este es un desajuste. Es posible que clientReady
permanezca establecido en true
, incluso si mBillingClient
es nulo. Creo que esto es lo que está pasando, al menos por mi error. Parece que algo impide que se llame a onBillingServiceDisconnected()
.
Puedo confirmar que no obtengo "billing client disconnected"
en logcat en unmount como se esperaba, por lo que onBillingServiceDisconnected()
hecho no se está llamando.
Corrección potencial : establezca clientReady = false
dentro del método endConnection()
(por ejemplo, después de la línea 179). Probé esto en el dispositivo y parece funcionar. Volver a montar el componente de compra en la aplicación varias veces no parece dar como resultado ningún error o bloqueo. Además, piense si es necesario establecer mBillingClient
en nulo. No tengo ninguna experiencia aquí, así que no puedo decirlo, pero parece un poco extraño. Tampoco veo ningún otro proyecto en Github que anule el cliente de facturación en esta devolución de llamada.
@ mitchellmcm27 Gracias por tu captura. Esto es muy prometedor y estoy de acuerdo contigo. Fue difícil para mí solucionar el problema sin una reproducción mínima. Además, me gustaría resolver los problemas juntos.
Por favor dénos cualquier PR
si tiene alguna idea de mejorar este problema.
Atentamente.
Lancé 2.4.0-beta6 en la última versión de mi aplicación, con algunos miles de actualizaciones hasta ahora. No hay bloqueos todavía 👍
Suena genial. ¡Muchas gracias por la solución! Cerraré este tema por ahora.
Ya tengo algunos fallos con el mismo stacktrace pero mucho menos que antes.
java.lang.RuntimeException:
at com.facebook.react.bridge.CallbackImpl.invoke (CallbackImpl.java:28)
at com.facebook.react.bridge.PromiseImpl.resolve (PromiseImpl.java:30)
at com.dooboolab.RNIap.RNIapModule$4.run (RNIapModule.java:155)
at com.dooboolab.RNIap.RNIapModule$3.onBillingSetupFinished (RNIapModule.java:124)
at com.android.billingclient.api.BillingClientImpl$BillingServiceConnection.onServiceConnected (BillingClientImpl.java:903)
at android.app.LoadedApk$ServiceDispatcher.doConnected (LoadedApk.java:1658)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run (LoadedApk.java:1687)
at android.os.Handler.handleCallback (Handler.java:789)
at android.os.Handler.dispatchMessage (Handler.java:98)
at android.os.Looper.loop (Looper.java:164)
at android.app.ActivityThread.main (ActivityThread.java:6944)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:327)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1374)
También sigue obteniendo el mismo stacktrace en 2.4.0-beta6
Creo que este error debería reabrirse.
120 choques en menos de 24 horas.
No estoy seguro de que los cambios recientes no hayan causado sus propios problemas, por ejemplo, si mBillingClient
no es nulo, pero aún no está listo, la función ensureConnection
simplemente sobrescribirá mBillingClient
con un nuevo cliente, desechando el anterior 🤔
Me gustaría saber qué versión comenzó a mostrar este error, para poder volver a una versión estable.
Yo también creo que el tema debería reabrirse. El problema original tenía que ver con la devolución de llamada, y las soluciones para eso surgieron el error de "referencia de objeto nulo". Aunque es posible que se haya solucionado este último (estoy de acuerdo con @LinusU en que puede haber más problemas allí), todavía estamos lidiando con el problema original.
También he tenido algunos fallos relacionados con la devolución de llamada en beta6.
He vuelto a abrir esto. Espero que alguien pueda dar PR
por esto.
¿Saben cuando se introdujo esto? Estaría más que feliz de retroceder.
Puedo confirmar que existen fallos en beta6 y 2.3.23 en Android. Bastante fácil de recrear según este [1] comentario.
Editar: Ahora que estoy en casa, estoy depurando el código nativo de Android para beta6. En caso de que esto sea útil, esto es lo que está sucediendo (al menos en mi aplicación, llamando a getAvailablePurchases):
Experimentaré matando al oyente una vez que ya no sea necesario.
[1]
https://github.com/googlesamples/android-play-billing/issues/45#issuecomment -324466519
He fusionado # 379 y lanzado a beta8
. Por favor intente eso.
¿Está arreglado en la última versión? ¿Es seguro actualizar a la última?
@hyochan este problema todavía aparece en 3.0.0-rc-2 ¿alguna idea?
java.lang.RuntimeException
com.dooboolab.RNIap.RNIapModule$3.onBillingSetupFinished
java.lang.RuntimeException:
at com.facebook.react.bridge.CallbackImpl.invoke (CallbackImpl.java:28)
at com.facebook.react.bridge.PromiseImpl.resolve (PromiseImpl.java:30)
at com.dooboolab.RNIap.RNIapModule$3.onBillingSetupFinished (RNIapModule.java:129)
at com.android.billingclient.api.BillingClientImpl$BillingServiceConnection$1.run (BillingClientImpl.java:1518)
at android.os.Handler.handleCallback (Handler.java:739)
at android.os.Handler.dispatchMessage (Handler.java:95)
at android.os.Looper.loop (Looper.java:148)
at android.app.ActivityThread.main (ActivityThread.java:7325)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1120)
@fokoz ¿Podrías probar 3.0.0-rc-4
? Funcionará perfectamente (con suerte).
@hyochan Si uso try catch
este error de tiempo de ejecución no ocurrirá, creo que rc-4 debería resolverlo.
Gracias !
Comentario más útil
@hyochan lo siento, no
@ Ilario17 Probablemente sea para señalar que hay un error lógico en alguna parte, para ser justos, no deberíamos llamar a ese método varias veces
edit: ah, el problema surge cuando
onBillingSetupFinished
ocurre más de una vez. En elensureConnection
necesitamos eliminar el oyente cuando hayamos terminado (es decir, cuando llamamos acallback.run()
o rechazamos la promesa pasada). ¡Debería ser un PR fácil si alguien quiere algo de karma gratis! De lo contrario, intentaré llegar pronto