使用react-native-iap时随机出现「未注册purchase-updated监听器」警告
React Native IAP iOS端随机出现“Sending
purchase-updated with no listeners registered.”警告及无响应问题 我把react-native-iap文档中的类组件监听器示例改成了函数组件写法(代码如下),但在iOS端完成购买时,会随机出现警告:Sending 'purchase-updated' with no listeners registered.,部分购买能正常触发purchaseUpdatedListener,部分则完全没反应。代码已经放在App.tsx中,试过调整代码位置但当前位置效果最佳,想知道有没有其他开发者碰到过同类问题。
useEffect(() => { const addListeners = async () => { await initConnection(); try { if (Platform.OS === SubscriptionPlatform.android) { return flushFailedPurchasesCachedAsPendingAndroid(); } } catch (error) { // Exception can happen here if there are pending purchases that are still pending // You can handle the error as per your requirements } const purchaseUpdateSubscription = purchaseUpdatedListener(async purchase => { console.log('purchaseUpdatedListener', purchase); if ( purchase?.productId && purchase?.transactionId && purchase?.transactionReceipt ) { await finishTransaction({ purchase }); } }); const purchaseErrorSubscription = purchaseErrorListener(error => { console.warn('purchaseErrorListener', error); }); return () => { if (purchaseUpdateSubscription) { purchaseUpdateSubscription.remove(); } if (purchaseErrorSubscription) { purchaseErrorSubscription.remove(); } endConnection(); }; }; addListeners(); }, []);
同类问题与解决方案
不少开发者都遇到过这个iOS端的随机问题,核心原因大多是监听器注册时机晚于购买事件触发,或者未处理APP启动时自动恢复的未完成交易,可以试试以下几种解决方法:
1. 提前注册监听器,不依赖initConnection完成
把监听器注册放在initConnection之前,确保即使初始化还在进行,系统触发的购买事件也能被捕获:
useEffect(() => { // 先注册监听器,再初始化连接 const purchaseUpdateSubscription = purchaseUpdatedListener(async purchase => { console.log('purchaseUpdatedListener', purchase); if ( purchase?.productId && purchase?.transactionId && purchase?.transactionReceipt ) { await finishTransaction({ purchase }); } }); const purchaseErrorSubscription = purchaseErrorListener(error => { console.warn('purchaseErrorListener', error); }); const initAndHandlePurchases = async () => { await initConnection(); try { if (Platform.OS === 'android') { await flushFailedPurchasesCachedAsPendingAndroid(); } } catch (error) { // 按需处理错误 } }; initAndHandlePurchases(); return () => { purchaseUpdateSubscription?.remove(); purchaseErrorSubscription?.remove(); endConnection(); }; }, []);
2. 手动检查并处理未完成交易
iOS会在APP启动时自动恢复未完成的交易,如果这时候监听器还没准备好,就会触发警告。可以在初始化后主动检查未完成交易:
const initAndHandlePurchases = async () => { await initConnection(); // 检查并处理启动时的未完成交易 const availablePurchases = await getAvailablePurchases(); for (const purchase of availablePurchases) { if (purchase?.productId && purchase?.transactionId && purchase?.transactionReceipt) { await finishTransaction({ purchase }); } } try { if (Platform.OS === 'android') { await flushFailedPurchasesCachedAsPendingAndroid(); } } catch (error) { // 按需处理错误 } };
3. 升级react-native-iap版本
部分旧版本的react-native-iap在iOS监听器注册逻辑上存在bug,升级到最新稳定版可能直接解决问题。
4. 确认组件未被意外卸载
虽然App.tsx作为根组件很少出现这种情况,但可以排查是否有路由逻辑或状态变化导致组件意外卸载,进而移除了监听器。
内容的提问来源于stack exchange,提问作者J.Kerminen
相关产品推荐
相关产品推荐

