4.4.6
0.61.5
ios
每次调用requestSubscription
之后,每次调用purchaseUpdatedListener
PurchaseUpdatedListener在应用启动时仅被调用一次,并且在requestSubscription调用之后从未调用
真实设备
只需遵循自述文件并尝试请求订阅
还有其他人有同样的问题吗? @Strate您给finishTransaction
打电话
@hyochan是的,但实际上此调用在应用程序重启后发生
@hyochan我已经尝试过expo-in-app-purchase软件包,并且没有这样的问题-evrything似乎很好
@Strate我想看你的代码。 我自己找不到任何错误:(
这个问题绝对令人发指。 是否有不是这种情况的先前版本?
还有其他人有同样的问题吗? @Strate您给
finishTransaction
打电话
由于购买是finishTransaction中的一个参数,这怎么可能? 因此,您需要事件监听器来获取传递给finishTransaction的参数。
@Sophrinix finishTransaction有望在purchaseUpdatedListener
内部调用
@hyochan对不起,但看来我现在没有实际的代码,我切换到expo-in-app-purchase
模块。 看起来@Sophrinix遇到相同的问题。
顺便说一句,我的代码中没有什么特别的:应用程序启动后立即注册侦听器,然后按照自述文件进行操作。
事实证明,这是一种回归。
如果使用以下版本,则一切正常:
"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.4.3
4.3.4
到4.4.3
工作正常,则问题出在4.4.4
如果我可以添加,从
4.4.3
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()
可能是因为自述文件中的示例缺少了它
升级到4.4.8时,iOS上出现了相同的问题,导致某些订阅未完成。 降级到4.4.3可以解决此问题。 是否必须使用initConnection()? 该文档使它看起来好像不是
遇到与我未添加initConnection()
调用相同的问题。
自述文件似乎只是在此处用粗体部分进行了更新:
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()
不在自述文件的示例代码中。 我在这里添加了它:#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;
很高兴它有所帮助。 自六月以来,我们已经开始生产该产品。
在某些时候它确实从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);
}
);
};
最有用的评论
遇到与我未添加
initConnection()
调用相同的问题。自述文件似乎只是在此处用粗体部分进行了更新:
我认为应该删除“在iOS上,它将仅调用canMakePayments”这一部分,并且还将
initConnection()
添加到基本示例中我真的坚信它是可选的,因为在示例中它不是
在注册购买监听器之前添加
initConnection()
对我来说已经解决了,所以这可能与#1002和#756有关