4.4.6
0.61.5
ios
purchaseUpdatedListener
requestSubscription
呼び出し後、毎回purchaseUpdatedListener
呼び出されます
PurchaseUpdatedListenerは、アプリの起動時に1回だけ呼び出され、requestSubscription呼び出しの後に呼び出されることはありません
実デバイス
readmeに従って、サブスクリプションをリクエストしてみてください
他に同じ問題を抱えている人はいますか? @StrateはfinishTransaction
電話しましたか?
@hyochanはい、しかし実際にはこの呼び出しはアプリの再起動後に発生します
@hyochan expo-in-app-purchaseパッケージを試しましたが、このような問題はありません-evrythingは問題ないようです
@Strateあなたのコードを見たいです。 自分でエラーを見つけることができません:(
この問題は絶対に腹立たしいです。 これが当てはまらない以前のバージョンはありますか?
他に同じ問題を抱えている人はいますか? @Strateは
finishTransaction
電話しましたか?
購入はfinishTransactionの議論であるため、これはどのように可能でしょうか? したがって、finishTransactionに渡す引数を取得するには、イベントリスナーが必要です。
@Sophrinix 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
電話したかどうかをもう一度確認してください。 これは最近のアップデートでの重要な変更であり、 android
ようにiOS
で呼び出す必要があります。
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
が機能していることも確認できます。
RN0.62.2とreact-native-iap4.4.8で数日間同じ問題が発生しました
initConnection()
見逃したのは、おそらくREADMEの例から欠落しているためです。
4.4.8にアップグレードしたときにiOSで同じ問題が発生し、一部のサブスクリプションが完了しませんでした。 今のところ、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、しかし誰かが私のコードを再確認することができれば、それはありがたいです。 (私はまだコードが完全に機能していないので、自信がありません...)
v5.1.1でもこの問題が発生していました。 initConnection
はそれを解決しませんでした。 リスナーのコールバックは、purchaseUpdateでトリガーされることはありません。 ただし、Androidでは問題なく動作します。 私の回避策は、 @ mrozanskiが行ったように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;
お役に立ててうれしいです。 これは6月から生産されています。
ある時点でObservableからこれに変更されました(typescriptは使用していません)
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);
}
);
};
最も参考になるコメント
initConnection()
呼び出しを追加しなかったのと同じ問題がありました。READMEは、ここの太字部分で更新されたようです。
この部分「iOSでは、単にcanMakePaymentsを呼び出す」を削除し、基本的な例に
initConnection()
を追加する必要があると思います。例に含まれていなかったので、オプションであると本当に確信しました
購入リスナーを登録する前に
initConnection()
追加すると、これが修正されたので、これはおそらく#1002と#756に関連しています。