React-native-iap: يتم استدعاء purchaseUpdatedListener مرة واحدة فقط عند بدء التطبيق ، ولا يتصل مطلقًا بعد مكالمة requestSubscription

تم إنشاؤها على ٢١ أبريل ٢٠٢٠  ·  22تعليقات  ·  مصدر: dooboolab/react-native-iap

نسخة من رد فعل - أصلية - IAP

4.4.6

نسخة من رد الفعل الأصلي

0.61.5

المنصات التي واجهت الخطأ فيها (IOS أو Android أو كليهما؟)

دائرة الرقابة الداخلية

سلوك متوقع

purchaseUpdatedListener استدعاء requestSubscription

السلوك الفعلي

يتم استدعاء purchaseUpdatedListener مرة واحدة فقط عند بدء التطبيق ، ولا يتصل مطلقًا بعد مكالمة requestSubscription

بيئة اختبار (محاكي؟ جهاز حقيقي؟)

جهاز حقيقي

خطوات إعادة إنتاج السلوك

فقط اتبع readme وحاول طلب الاشتراك

📱 iOS 🕵️‍♂️ need more investigation 🙏 help wanted

التعليق الأكثر فائدة

واجهت نفس المشكلة حيث لم أقم بإضافة مكالمة initConnection() .
يبدو أن README قد تم تحديثه للتو بالجزء الجريء هنا:

initConnection() على نظام التشغيل iOS ، سيستدعي ببساطة طريقة canMakePayments وقيمة الإرجاع __التي هي مطلوبة حتى يعمل المستمعون بشكل صحيح.

أعتقد أنه يجب إزالة هذا الجزء "على iOS ، سيستدعي canMakePayments" ، كما يجب إضافة initConnection() إلى المثال الأساسي

كنت مقتنعًا حقًا أنه كان اختياريًا لأنه لم يكن في المثال

أدت إضافة initConnection() قبل تسجيل مستمع / مستمع الشراء إلى إصلاح هذا بالنسبة لي ، لذلك من المحتمل أن يكون هذا مرتبطًا بـ # 1002 و # 756

ال 22 كومينتر

هل هناك أي شخص آخر لديه نفس المشكلة؟ Strate هل اتصلت بـ finishTransaction ؟

hyochan نعم ، ولكن في الواقع تحدث هذه المكالمة بعد إعادة تشغيل التطبيق

hyochan لقد جربت Purchase ، ولا توجد مشكلة كهذه - يبدو أن كل شيء على ما يرام

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 . هذه تغييرات مهمة في التحديث الأخير الذي من الضروري الآن أن يتم استدعاؤك بـ iOS كما في android .

أؤكد أن العودة إلى 4.3.0 يعمل. كنت أتعامل مع أحدث إصدار ، لقد كنت أقوم بتصحيح الأخطاء لأكثر من ساعة في محاولة للعثور على المشكلة.

إذا كان بإمكاني إضافة ، فإن 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 يعمل.

عانيت من نفس المشكلة لبضعة أيام مع RN 0.62.2 ورد الفعل الأصلي - iap 4.4.8
لقد فاتني بطريقة ما initConnection() ربما لأنه مفقود من المثال في README

واجهت نفس المشكلة على iOS عند الترقية إلى 4.4.8 مما جعل بعض الاشتراكات غير مكتملة. أدى الرجوع إلى الإصدار 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 ، ولكن إذا تمكن أي شخص من التحقق من الكود الخاص بي ، فسيكون موضع تقدير. (ما زلت لا أملك الكود الخاص بي يعمل بشكل كامل ، لذا فأنا لست واثقًا جدًا من ذلك ...)

كنت أواجه هذه المشكلة أيضًا في الإصدار 5.1.1. initConnection لم يحل المشكلة. لا يتم تشغيل عمليات رد نداء المستمع أبدًا عند PurchaseUpdate. يعمل بشكل جيد على الرغم من الروبوت. كان الحل البديل هو استخدام 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;

سعيد لأنه ساعد. لدينا هذا في الإنتاج منذ يونيو.
لقد تغيرت من ملحوظة إلى هذا في مرحلة ما (نحن لا نستخدم الكتابة المطبوعة)

      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);
        }
      );
    };
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات