"react-native"ïŒ "0.55.4"
"react-native-iap"ïŒ "^ 2.3.2"
ã¢ã³ããã€ã
ç§ãå©ããŠãã ãããç§ã¯ãããããã«ä¿®æ£ããå¿ èŠããããŸãã ãã§ã«+2000人ã®ãŠãŒã¶ãŒããããã
å€ãã®ããã€ã¹ã§rniapãåå ã§ã¢ããªãã¯ã©ãã·ã¥ããŸãã åçã³ã³ãœãŒã«ã§ããã®ãšã©ãŒãã¯ã©ãã·ã¥ã®åå ã§ããããšãããããŸããã
java.lang.RuntimeExceptionïŒ
ããããã¬ã€ã³ã³ãœãŒã«ããã®ã¬ããŒãã§ãïŒ
https://ibb.co/gDxZQA
ã©ãããããããããããªãã®ã§ãäŸã®ããã«rniapã䜿ããŸããã
componentDidMountå
ïŒ
{ãè©ŠããŠãã ãã
const result = await RNIap.initConnectionïŒïŒ;
} catchïŒerrïŒ{
console.logïŒerrïŒ;
}
componentWillUnmountïŒ
RNIap.endConnectionïŒïŒ;
æè¿ã®ããŒãžã§ã³2.3.19
ãšã«ã ããã¯ãè©ŠããŠããã ããŸãããïŒ
ã§ããŸããã ããã¯åœé¢ã®ç¶æ³ã ã£ãããã§ãã ããã§ãiapããã±ãŒãžãå€æŽããŸããã + 3kãŠãŒã¶ãŒã§ã¯ã©ãã·ã¥ã¯çºçããŸããã ã§ãããããšãã 次ã®ãããžã§ã¯ãã§è©ŠããŠã¿ãŸãã
ããã«ã¡ã¯ããã®åé¡ãåéã§ããŸããïŒ åãåé¡ããããããŒãžã§ã³2.3.21ã䜿çšããŠããŸã
java.lang.RuntimeExceptionïŒ
com.facebook.react.bridge.CallbackImpl.invokeïŒCallbackImpl.java:28ïŒã§
com.facebook.react.bridge.PromiseImpl.resolveïŒPromiseImpl.java:30ïŒã§
com.dooboolab.RNIap.RNIapModule $ 4.runïŒRNIapModule.java:155ïŒã§
com.dooboolab.RNIap.RNIapModule $ 3.onBillingSetupFinishedïŒRNIapModule.java:124ïŒã§
com.android.billingclient.api.BillingClientImpl $ BillingServiceConnection.onServiceConnectedïŒBillingClientImpl.java:903ïŒã§
android.app.LoadedApk $ ServiceDispatcher.doConnectedïŒLoadedApk.java:1658ïŒã§
android.app.LoadedApk $ ServiceDispatcher $ RunConnection.runïŒLoadedApk.java:1687ïŒã§
android.os.Handler.handleCallbackïŒHandler.java:789ïŒã§
android.os.Handler.dispatchMessageïŒHandler.java:98ïŒã§
android.os.Looper.loopïŒLooper.java:164ïŒã§
android.app.ActivityThread.mainïŒActivityThread.java:6938ïŒã§
java.lang.reflect.Method.invokeïŒãã€ãã£ãã¡ãœããïŒã§
com.android.internal.os.Zygote $ MethodAndArgsCaller.runïŒZygote.java:327ïŒã§
com.android.internal.os.ZygoteInit.mainïŒZygoteInit.java:1374ïŒã§
ããã¯ç§ã®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ããã§ç§ãã¡ãå©ããŠãããŸãããïŒ ãªãªãŒã¹æã«callback.run()
ã¯ã©ãã·ã¥ããã®ã¯ãªãã§ããïŒ ensureConnection
callback
ãnullãã©ããã確èªããå¿
èŠããããŸããïŒ ããŒãã runtime exception
ã§ãã
ããŒããããã§RuntimeException
ã©ãããæå³ã§ããããã以äžã®æ
å ±ã¯ãããŸãããïŒ @hyochanãªãcallback
ãnull
æããŸããïŒ ð€
@LinusUãã£ãŒãããã¯ãããããšãããããŸãã ä»ã¯ããããŸããã 以äžã®åé¡è¡ãèŠããšããã§ãã
RNIapModule.java
è¡124ã§ã
callback.run();
ä»ã«äœãã¢ã€ãã¢ã¯ãããŸããïŒ
@LinusUããã«ã€ããŠäœãããããªãå Žåã¯ã以åã®å Žæã«ããŒã«ããã¯ããããšãæ€èšããŸãã
ããŠãããã«åé¡ããããŸãïŒ
äœããã®çç±ã§ãã³ãŒã«ããã¯ãè€æ°ååŒã³åºããŠããŸãããç°¡åã«ä¿®æ£ã§ããã¯ãã§ãã
@LinusUããªãããã©ãã¯ã«ããã®ã§ãPR
ãæããŠããã ããŸããïŒ
ãã®ã¡ãœããã«RuntimeExceptionãããã®ã¯ãªãã§ããïŒ
if (!mInvoked) {
mJSInstance.invokeCallback(mCallbackId, Arguments.fromJavaArgs(args));
mInvoked = true;
}
ãã®ãããªãã®ã§ã¯ååã§ã¯ãããŸãããïŒ
@hyochanç³ãèš³ãããŸããããæšæ¥ãããèŠãæéããããŸããã§ãããããŸãããã°ç§ã¯ããã«èŠãããšãã§ããŸã
@ Ilario17ãããããã©ããã«è«çãšã©ãŒãããããšã瀺ããã©ã°ãç«ãŠãããŸããå ¬å¹³ãæãããã«ããã®ã¡ãœãããè€æ°ååŒã³åºãã¹ãã§ã¯ãããŸããã
ç·šéïŒãããåé¡ã¯onBillingSetupFinished
ãè€æ°åçºçãããšãã«çºçããŸãã ensureConnection
ã§ã¯ãå®äºãããïŒã€ãŸãã callback.run()
ãåŒã³åºãããæž¡ãããçŽæãæåŠãããšãã«ïŒãªã¹ããŒãåé€ããå¿
èŠããããŸãã 誰ããç¡æã®ã«ã«ããæ±ããŠãããªããç°¡åãªPRã«ãªãã¯ãã§ãïŒ ããã§ãªããã°ç§ã¯ããã«ããã«å°éããããšããŸã
@LinusUã€ãŸãã onBillingSetupFinished
ããšã§ããã billingClientStateListener
ãåé€ããå¿
èŠããããŸããïŒ èª°ããç§ãã¡ã®äžéšã«ãªãããã«ãããè©ŠããŠã¿ãŸãããïŒ
è¿
éã§æ±ã解決çãå¿
èŠãªå Žåã¯ããã®é¢æ°ã«ããŒã«ã«å€æ°didCallCallback = false
ãè¿œå ããŸãã 次ã«ã if (didCallCallback) { didCallCallback = true; callback.run() }
èåŸã«ããcallback.run()
ãžã®åŒã³åºããä¿è·ããŸãã
ããã¯ãªãŒã³ãªè§£æ±ºçã¯ãæåã®åŒã³åºãã®åŸã§ãªã¹ããŒã®ç»é²ãå®å šã«è§£é€ããããšã§ã...
Log.d(TAG, "billing client ready");
callback.run();
//deregister the listener here?
ãããä¿®æ£ããããã«2.4.0-beta2
ããªãªãŒã¹ããŸããã ããŠã¿ãŠãã ããã
@hyochanãã®æ°ããããŒãžã§ã³ãè©ŠããŠã¿ãŸã
beta2ã«ã¯ååž°ã®åé¡ããã£ãããã2.4.0-beta3ãè©ŠããŠãã ããã
æŽæ°åŸã®@hyochanãšã©ãŒã¯ãŸã ãããŸã:(
@ Ilario17 2.4.0-beta5
ã©ãã§ããïŒ ç§ã®åŽã§ã¯ãããåçŸã§ããªãã®ã§ãããªãã®ãã¹ããå¿
èŠã§ã:(
@LinusUãèšã£ãããã«@hyochançç±ã ãã§ã¯ãªãããªã¹ããŒãåé€ããŸããïŒ
@ Ilario17ãããæ£ãã解決çãã©ããèå³ããããŸããã ãŸãã onBillingServiceDisconnected
ãéç¥ããå¿
èŠããããšæããŸãã ããªãã¯ãããåé€ããŠããªãã®åŽã§ããããã¹ããããããæ©èœãããã©ããã確èªããããšãããããããŸããã
ãããé¢é£ããŠãããã©ããã¯ããããŸãããã2.4.0-beta5ã§ãã®ã¯ã©ãã·ã¥ãçºçããŠããŸãã ãšãã¥ã¬ãŒã¿ãŒã§åçŸããã®ã¯ç°¡åã§ãïŒ
IAPãããŒããããå Žæã«ã³ã³ããŒãã³ããããŠã³ãããããŠã³ãã解é€ããŠããå床ããŠã³ããããšãããŒã ãã¯ã©ãã·ã¥ããŸãã
ç·šéïŒãã®ã³ãããã«ããŠã³ã°ã¬ãŒãããŸããããã¯ã©ãã·ã¥ããªããªããŸãã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
2çªç®ã®ããŠã³ãïŒ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ãŸãããã¯Androidãšãã¥ã¬ãŒã¿ã§ã¯æ©èœããŸããã å®éã®ããã€ã¹ã§ãè©Šããã ããã
@hyochanããŒãžã§ã³2.4.0-
Androidã®2.4.0-beta3ã®å ŽåãgetProductsãåŒã³åºãã ãã§ããã³ãŒãã§è³Œå ¥ã«å€±æããŸããïŒ0ïŒOKïŒããšãããšã©ãŒãçºçããŸãã ããŒã¿4ãš5ã¯ãå®éã«ã¯ã©ãã·ã¥ãåŒãèµ·ãããŸãã 2.3.5ã«ããŠã³ã°ã¬ãŒãããŸããããæ£åžžã«åäœããŸããã2.4.0ããŒã¿çã®iOSãªã¹ããŒã®ãã°ä¿®æ£ãå¿ èŠã§ãã
`` `
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)
}
};
beta5ãšã«ã ããã¯ãè©ŠããŠããã ããŸããïŒ ãã®ããŒãžã§ã³ã«ééãããã£ãã®ã§ãããã«ä¿®æ£ããŸãã
@ hyochan @ LinusUããŒãžã§ã³2.4.0-beta5ã§ã¯ãšã©ãŒããŸã çºçããŠããŸãã
ãã®è°è«ã«é¢é£ããæ å ±ãããã€ããããŸãã
2.4.0-beta5ã§ã次ã®ãšã©ãŒãçºçããŸã
Attempt to invoke virtual method void com.android.billingclient.api.BillingClient.querySkuDetailsAsync(...) on a null object reference
RNIapModule.java
223è¡ç®ãæããŠããŸããããã¯ã mBillingClient
ãäºæããnull
ã§ããããšãæå³ããŸãã
åçŸããã«ã¯ã次RNIap.getProducts()
ã«componentDidMount
ãšRNIap.endConnection()
ã®componentWillUnmount
ã ã³ã³ããŒãã³ããã¢ã³ããŠã³ãããŠãå床ããŠã³ãããŸãã äžèšã®ãšã©ãŒãçºçããã¯ãã§ãã
å€æ°clientReady
ã¯ã onBillingServiceDisconnected()
ã³ãŒã«ããã¯ã§false
ã«èšå®ããããšã«ããã課éã¯ã©ã€ã¢ã³ãã®ã»ããã¢ãããå®äºãããã©ããã远跡ããããã«äœ¿çšãããŠããŸãã ãã ãã mBillingClient
èªäœã¯ã endConnection()
ãåŒã³åºããããšããã«nullã«èšå®ãããŸãã ããã¯äžäžèŽã§ãã mBillingClient
ãnullã®å Žåã§ãã clientReady
ãtrue
ã«èšå®ããããŸãŸã«ãªãå¯èœæ§ããããŸãã å°ãªããšãç§ã®ééãã«ã€ããŠã¯ããããèµ·ãã£ãŠããããšã ãšæããŸãã äœããonBillingServiceDisconnected()
åŒã³åºãã劚ããŠããããã§ãã
æåŸ
ã©ããã«ã¢ã³ããŠã³ãæã«logcatã§"billing client disconnected"
ãååŸããŠããªãããšã確èªã§ããããã onBillingServiceDisconnected()
ã¯å®éã«åŒã³åºãããŠããŸããã
ä¿®æ£ã®å¯èœæ§ïŒ endConnection()
ã¡ãœããå
ã«clientReady = false
ãŸãïŒããšãã°ã179è¡ç®ä»¥éïŒã ç§ã¯ãããããã€ã¹ã§ãã¹ãããŸããããåäœããŠããããã§ãã ã¢ããªå
賌å
¥ã³ã³ããŒãã³ããè€æ°ååããŠã³ãããŠãããšã©ãŒãã¯ã©ãã·ã¥ã¯çºçããªãããã§ãã ãŸãã mBillingClient
ãnullã«èšå®ããå¿
èŠããããã©ãããèããŠã¿ãŠãã ããã ç§ã¯ããã§ã®çµéšããªãã®ã§èšãããšã¯ã§ããŸããããå°ãå¥åŠã«æããŸãã ãŸãããã®ã³ãŒã«ããã¯ã§è«æ±ã¯ã©ã€ã¢ã³ããç¡å¹ã«ããGithubäžã®ä»ã®ãããžã§ã¯ãã¯èŠåœãããŸããã
@ mitchellmcm27ãã£ããããŠãããŠããããšãã ããã¯éåžžã«ææã§ãããç§ã¯ããªãã«åæããŸãã æå°éã®åçŸãªãã§åé¡ã解決ããããšã¯ç§ã«ãšã£ãŠå°é£ã§ããã ãŸããäžç·ã«åé¡ã解決ããããšæããŸãã
ãã®åé¡ã匷åããããšãèããŠããå Žåã¯ã PR
ãæããŠãã ããã
å®ãããé¡ãããŸãã
ç§ã®ã¢ããªã®ææ°ããŒãžã§ã³ã§2.4.0-beta6ããªãªãŒã¹ããŸãããããããŸã§ã«æ°åã®ã¢ããã°ã¬ãŒãããããŸããã ãŸã ã¯ã©ãã·ã¥ã¯ãããŸããð
ãããã ä¿®æ£ããŠããã ãããããšãããããŸãïŒ ãšãããããã®å·ãéããŸãã
ç§ã¯ãã§ã«åãã¹ã¿ãã¯ãã¬ãŒã¹ã§ããã€ãã®ã¯ã©ãã·ã¥ããããŸããã以åããã¯ããã«å°ãªãã§ãã
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)
ãŸãã2.4.0-beta6ã§ãåãã¹ã¿ãã¯ãã¬ãŒã¹ãååŸããŠããŸã
ãã®ãã°ã¯åéããå¿ èŠããããšæããŸãã
24æé以å ã«120ãã¯ã©ãã·ã¥ããŸãã
æè¿ã®å€æŽãç¬èªã®åé¡ãåŒãèµ·ãããŠããªããã©ããã¯ããããŸãããããšãã°ã mBillingClient
ãnullã§ãªããããŸã æºåãã§ããŠããªãå Žåã ensureConnection
é¢æ°ã¯åã«mBillingClient
äžæžãããŸããæ°ããã¯ã©ã€ã¢ã³ãã§
å®å®ããããŒãžã§ã³ã«ããŒã«ããã¯ã§ããããã«ãã©ã®ããŒãžã§ã³ã§ãã®ãšã©ãŒã衚瀺ããå§ããããç¥ãããã®ã§ããã
ç§ãåé¡ãåéãã¹ãã ãšæããŸãã å ã®åé¡ã¯ã³ãŒã«ããã¯ã«é¢ä¿ããŠããããã®ä¿®æ£ã«ãããnullãªããžã§ã¯ãåç §ããšã©ãŒãçºçããŸããã åŸè ã¯ä¿®æ£ãããå¯èœæ§ããããŸããïŒ @LinusUã«ã¯ããã«åé¡ãããå¯èœæ§ãããããšã«åæã
beta6ã®ã³ãŒã«ããã¯ã«é¢é£ããã¯ã©ãã·ã¥ãããã€ãçºçããŸããã
ãããåéããŸããã 誰ããããã«PR
ãäžããããšãã§ããããšãé¡ã£ãŠããŸãã
ããããã€å°å ¥ããããç¥ã£ãŠããŸããïŒ ããŒã«ããã¯ã§ããã°å¹žãã§ãã
ã¯ã©ãã·ã¥ã¯beta6ãšAndroidã®2.3.23ã«ååšããããšã確èªã§ããŸãã ãã®[1]ã³ã¡ã³ãã«åŸã£ãŠãããªãç°¡åã«åäœæã§ããŸãã
ç·šéïŒå®¶ã«ããã®ã§ãbeta6ã®Androidãã€ãã£ãã³ãŒãã«ãããã°ããŠããŸãã ããã圹ç«ã€å Žåããããèµ·ãã£ãŠããããšã§ãïŒå°ãªããšãç§ã®ã¢ããªã§ã¯ãgetAvailablePurchasesãåŒã³åºããŸãïŒïŒ
ãªã¹ããŒãäžèŠã«ãªã£ããããªã¹ããŒãåé€ããŠã¿ãŸãã
[1]
https://github.com/googlesamples/android-play-billing/issues/45#issuecomment -324466519
ïŒ379ãããŒãžããŠã beta8
ãªãªãŒã¹ããŸããã ãã²ãè©Šããã ããã
ããã¯ææ°ããŒãžã§ã³ã§ä¿®æ£ãããŠããŸããïŒ ææ°ã«ã¢ããã°ã¬ãŒãããŠãå®å šã§ããïŒ
@hyochanãã®åé¡ã¯ãŸã 3.0.0-rc-2ã«è¡šç€ºãããŸãã
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 3.0.0-rc-4
ãè©ŠããŠããã ããŸãããïŒ ããã¯å®å
šã«æ©èœããŸãïŒããŸãããã°ïŒã
@hyochan try catch
ã䜿çšãããšããã®ã©ã³ã¿ã€ã ãšã©ãŒã¯çºçããŸããããrc-4ã§è§£æ±ºã§ãããšæããŸãã
ããããšãããããŸãã ïŒ
æãåèã«ãªãã³ã¡ã³ã
@hyochanç³ãèš³ãããŸããããæšæ¥ãããèŠãæéããããŸããã§ãããããŸãããã°ç§ã¯ããã«èŠãããšãã§ããŸã
@ Ilario17ãããããã©ããã«è«çãšã©ãŒãããããšã瀺ããã©ã°ãç«ãŠãããŸããå ¬å¹³ãæãããã«ããã®ã¡ãœãããè€æ°ååŒã³åºãã¹ãã§ã¯ãããŸããã
ç·šéïŒãããåé¡ã¯
onBillingSetupFinished
ãè€æ°åçºçãããšãã«çºçããŸããensureConnection
ã§ã¯ãå®äºãããïŒã€ãŸããcallback.run()
ãåŒã³åºãããæž¡ãããçŽæãæåŠãããšãã«ïŒãªã¹ããŒãåé€ããå¿ èŠããããŸãã 誰ããç¡æã®ã«ã«ããæ±ããŠãããªããç°¡åãªPRã«ãªãã¯ãã§ãïŒ ããã§ãªããã°ç§ã¯ããã«ããã«å°éããããšããŸã