React-native-iap: يتعطل Android في العديد من الأجهزة بعد الإصدار

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

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

"تفاعل أصلي": "0.55.4"
"رد فعل - أصلي - iap": "^ 2.3.2"

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

ذكري المظهر

سلوك متوقع

الرجاء مساعدتي ، أحتاج إلى إصلاح هذا على الفور. لأنه يوجد بالفعل + 2k مستخدم

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

تعطل التطبيق بسبب rniap في العديد من الأجهزة. في وحدة التحكم في Play ، رأيت أن هذا الخطأ يسبب التعطل:
java.lang.RuntimeException:

  1. على com.facebook.react.bridge.CallbackImpl.invoke (CallbackImpl.java:28)
  2. في com.facebook.react.bridge.PromiseImpl.resolve (PromiseImpl.java:30)
  3. في com.dooboolab.RNIap.RNIapModule 4.run (RNIapModule.java:154)
  4. في com.dooboolab.RNIap.RNIapModule 3. $ على إعداد الفواتير (RNIapModule.java:123)
  5. على com.android.billingclient.api.BillingClientImpl $ BillingServiceConnection.onServiceConnected (BillingClientImpl.java:903)
  6. على android.app.LoadedApk $ ServiceDispatcher.doConnected (LoadedApk.java:1264)
  7. على android.app.LoadedApk $ ServiceDispatcher $ RunConnection.run (LoadedApk.java:1281)
  8. على android.os.Handler.handleCallback (Handler.java:815)
  9. على android.os.Handler.dispatchMessage (Handler.java:104)
  10. على android.os.Looper.loop (Looper.java:207)
  11. على android.app.ActivityThread.main (ActivityThread.java:5692)
  12. على java.lang.reflect.Method.invoke (الطريقة الأصلية)
  13. على com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:908)
  14. في com.android.internal.os.ZygoteInit.main (ZygoteInit.java:769)

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

هذا هو التقرير من Play Console:
https://ibb.co/gDxZQA

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

لا أعرف ماذا أفعل ، لقد استخدمت rniap على سبيل المثال.
في componentDidMount:
محاولة {
نتيجة const = انتظار RNIap.initConnection () ؛
} catch (يخطئ) {
console.log (يخطئ) ؛
}
في componentWillUnmount:
RNIap.endConnection () ،

🐛 bug 🤖 android

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

hyochan آسف ، لم أحصل على الوقت للنظر في هذا أمس ، آمل أن أتمكن من إلقاء نظرة قريبًا

@ Ilario17 من المحتمل الإشارة إلى وجود خطأ منطقي في مكان ما ، لكي نكون منصفين ، لا ينبغي أن نطلق على هذه الطريقة عدة مرات

تحرير: آه ، المشكلة تأتي عندما يحدث onBillingSetupFinished أكثر من مرة. في ensureConnection نحتاج إلى إزالة المستمع عند الانتهاء (على سبيل المثال عندما نتصل بـ callback.run() أو نرفض الوعد الذي تم تمريره). يجب أن تكون علاقات عامة سهلة إذا كان أي شخص لديه بعض الكارما المجانية! وإلا سأحاول الوصول إليه قريبًا

ال 45 كومينتر

هل يمكنك تجربة نسختنا الأخيرة 2.3.19 والعودة؟

لا استطيع. لأنها كانت حالة فورية. لذلك ، قمت بتغيير حزمة iap. الآن لا توجد أعطال في + 3 آلاف مستخدم. لكن شكرا لك. سأحاول ذلك في مشروعي القادم.

مرحبًا ، هل يمكنك إعادة فتح هذه المشكلة؟ لدي نفس المشكلة وأنا أستخدم الإصدار 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. $ على إعداد الفواتير (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() في الإصدار؟ هل يجب أن نتحقق مما إذا كان callback فارغًا في ensureConnection ؟ جلالة الملك. إنه runtime exception .

هممم ، ماذا يعني RuntimeException هنا ، أليس هناك مزيد من المعلومات؟ hyochan لماذا تعتقد أن callback كان null ؟ 🤔

LinusU شكرا لملاحظاتك. ليس لدي فكرة حاليا. لقد رأيت للتو سطر المشكلة أدناه.
image

في RNIapModule.java سطر 124 ،

callback.run();

هل لديك أي فكرة أخرى؟

LinusU إذا لم يكن لديك أي فكرة عن هذا ،

حسنًا ، ها هي المشكلة:

https://github.com/facebook/react-native/blob/370bcffba748e895ad8afa825bfef40bff859c95/ReactAndroid/src/main/java/com/facebook/react/bridge/CallbackImpl.java#L27 -L31

لسبب ما نقوم باستدعاء رد الاتصال أكثر من مرة ، يجب أن يكون من السهل إصلاحه!

LinusU تبدو رائعة لأنك في المسار الصحيح! هل يمكن أن تعطينا PR لهذا؟

لماذا يوجد RuntimeException بهذه الطريقة؟

if (!mInvoked) {
   mJSInstance.invokeCallback(mCallbackId, Arguments.fromJavaArgs(args));
   mInvoked = true;
}

لا يكفي شيء من هذا القبيل؟

hyochan آسف ، لم أحصل على الوقت للنظر في هذا أمس ، آمل أن أتمكن من إلقاء نظرة قريبًا

@ Ilario17 من المحتمل الإشارة إلى وجود خطأ منطقي في مكان ما ، لكي نكون منصفين ، لا ينبغي أن نطلق على هذه الطريقة عدة مرات

تحرير: آه ، المشكلة تأتي عندما يحدث onBillingSetupFinished أكثر من مرة. في ensureConnection نحتاج إلى إزالة المستمع عند الانتهاء (على سبيل المثال عندما نتصل بـ callback.run() أو نرفض الوعد الذي تم تمريره). يجب أن تكون علاقات عامة سهلة إذا كان أي شخص لديه بعض الكارما المجانية! وإلا سأحاول الوصول إليه قريبًا

LinusU إذن هل تقصد onBillingSetupFinished ، يجب علينا إزالة billingClientStateListener ؟ هل يجرب شخص ما هذا ليكون جزءًا منا؟

إذا كنت تريد حلاً سريعًا وقذرًا ، فسأضيف متغيرًا محليًا إلى هذه الوظيفة ، didCallCallback = false . ثم قم بحماية المكالمة إلى callback.run() خلف if (didCallCallback) { didCallCallback = true; callback.run() } .

سيكون الحل الأنظف ببساطة هو إلغاء تسجيل المستمع بعد المكالمة الأولى تمامًا ...

Log.d(TAG, "billing client ready");
callback.run();
//deregister the listener here?

لقد أصدرت للتو 2.4.0-beta2 لإجراء إصلاحات على هذا. أرجوك حاول.

hyochan سأحاول هذا الإصدار الجديد

يرجى تجربة الإصدار 2.4.0-beta3 نظرًا لأن beta2 كان يعاني من مشكلة الانحدار.

hyochan بعد التحديث ، لا يزال الخطأ موجود :(

@ Ilario17 ماذا عن 2.4.0-beta5 ؟ نظرًا لأنني لا أستطيع إعادة إنتاج هذا من جانبي ، فأنا بحاجة إلى اختبارك :(

hyochan لماذا لا تزيل المستمع فقط ، كما قال LinusU ؟

@ 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.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-beta3 به تحطم أقل بنسبة 50٪ ، لكنه لا يزال غير كافٍ

بالنسبة لـ 2.4.0-beta3 على Android ، يظهر لي خطأ "فشلت عملية الشراء برمز: 0 (OK)" فقط من استدعاء getProducts. بيتا 4 و 5 يتسببان في تحطمها. لقد خفضت إصداره إلى 2.3.5 وهو يعمل بشكل جيد ، لكنني بحاجة إلى إصلاحات أخطاء مستمع ios في الإصدار 2.4.0 بيتا

""
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 والعودة؟ كان هناك خطأ في هذا الإصدار لذا أصلحته بسرعة

hyochanLinusU مع النسخة 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 line 223. هذا يعني أن mBillingClient بشكل غير متوقع null هنا.

لإعادة الإنتاج : قم بتركيب مكون أصلي يستدعي RNIap.getProducts() على componentDidMount و RNIap.endConnection() على componentWillUnmount . قم بإلغاء تحميل المكون وتركيبه مرة أخرى. يجب أن يحدث الخطأ أعلاه.

يتم استخدام المتغير clientReady لتتبع ما إذا كان إعداد عميل الفوترة قد اكتمل ، وذلك بتعيينه على false في رد الاتصال onBillingServiceDisconnected() . لكن mBillingClient نفسه مضبوط على null فور استدعاء endConnection() . هذا عدم تطابق. من الممكن أن يظل clientReady مضبوطًا على true ، حتى لو كان mBillingClient فارغًا. أعتقد أن هذا ما يحدث ، على الأقل بسبب خطأي. يبدو أن شيئًا ما يمنع استدعاء onBillingServiceDisconnected() .

أستطيع أن أؤكد أنني لا أحصل على "billing client disconnected" في logcat عند إلغاء التحميل كما هو متوقع ، لذلك لم يتم استدعاء onBillingServiceDisconnected() بالفعل.

الإصلاح المحتمل : clientReady = false ضمن طريقة endConnection() (على سبيل المثال بعد السطر 179). لقد اختبرت هذا على الجهاز ويبدو أنه يعمل. لا يبدو أن إعادة تركيب مكون الشراء داخل التطبيق عدة مرات يؤدي إلى أي أخطاء أو أعطال. أيضًا ، فكر فيما إذا كان من الضروري تعيين mBillingClient على قيمة خالية؟ ليس لدي أي خبرة هنا لذلك لا يمكنني القول ، لكن يبدو الأمر غريبًا بعض الشيء. لا أرى أيضًا أي مشاريع أخرى على Github تلغي عميل الفوترة في رد الاتصال هذا.

@ mitchellmcm27 شكرا

يرجى إعطائنا أي PR إذا كان لديك أي تفكير في تحسين هذه المشكلة.

تحياتي الحارة.

لقد قمت بإصدار 2.4.0-beta6 في أحدث إصدار من تطبيقي ، مع بضعة آلاف من الترقيات حتى الآن. لا توجد حوادث بعد 👍

يبدو عظيما. شكرا جزيلا على الإصلاح لك! سأغلق هذه القضية الآن بعد ذلك.

لدي بالفعل بعض التعطل مع نفس Stacktrace ولكن أقل بكثير من ذي قبل.


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)

لا يزال يتم أيضًا الحصول على نفس نظام Stacktrace على 2.4.0-beta6

أعتقد أنه يجب إعادة فتح هذا الخطأ.

schermata 2019-01-11 alle 10 51 20

120 تحطم في أقل من 24 ساعة.

لست متأكدًا من أن التغييرات الأخيرة لم تتسبب في مشاكلهم الخاصة ، على سبيل المثال ، إذا لم يكن mBillingClient فارغًا ، لكنه لم يكن جاهزًا بعد ، ensureConnection الوظيفة mBillingClient مع عميل جديد ، التخلص من العميل القديم 🤔

أرغب في معرفة الإصدار الذي بدأ يظهر هذا الخطأ ، حتى أتمكن من العودة إلى إصدار ثابت.

أنا أيضا أعتقد أنه يجب إعادة فتح القضية. كانت المشكلة الأصلية تتعلق برد الاتصال ، وظهرت الإصلاحات لذلك الخطأ "مرجع كائن فارغ". على الرغم من أنه ربما تم إصلاح الأخير (أتفق مع LinusU على أنه قد يكون هناك المزيد من المشاكل) ، ما زلنا نتعامل مع المشكلة الأصلية.

لقد تلقيت بعض الأعطال المتعلقة بإعادة الاتصال في beta6 أيضًا.

لقد أعدت فتح هذا. آمل أن يتمكن شخص ما من التبرع بـ PR لهذا الغرض.

هل تعلمون متى تم تقديم هذا؟ سأكون أكثر من سعيد للتراجع.

يمكنني التأكد من وجود الأعطال في beta6 وكذلك 2.3.23 على Android. من السهل إلى حد ما إعادة الإنشاء وفقًا لهذا التعليق [1].

تحرير: الآن بعد أن أصبحت في المنزل ، أقوم بتصحيح الأخطاء في رمز Android الأصلي لـ beta6. في حال كان هذا مفيدًا ، هذا ما يحدث (على الأقل في تطبيقي ، استدعاء getAvailablePurchases):

  1. يتم استدعاء getAvailableItemsByType لـ "inapp" بدون إعداد mBillingClient حتى الآن.
  2. يتم إعداد عميل الفوترة ، ويتم استدعاء onBillingSetupFinished في المستمع ، ويتم استهلاك رد الاتصال (الوعد) (تم حله). المستمع لا يزال موجودا.
  3. يتم استدعاء getAvailableItemsByType لـ "subs" من خلال إعداد mBillingClient. تم استهلاك رد الاتصال الجديد (الوعد) (تم حله).
  4. اقتل خدمة متجر Play - يُطلق على onServiceDisconnected في BillingClientImpl ، ويتولى المستمع من الجزء الأول التعامل معها. تبدأ خدمة جديدة ، ويعالج المستمع من الجزء الأول onBillingSetupFinished ، ويحاول استهلاك رد الاتصال (الوعد) من الخطوة الأولى ، يُطلب مرة أخرى.

سأجرب قتل المستمع بمجرد عدم الحاجة إليه.

[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 يجب أن يحل هذا.
شكرا جزيلا !

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

ramondelmondo picture ramondelmondo  ·  4تعليقات

jvandenaardweg picture jvandenaardweg  ·  4تعليقات

coldfins picture coldfins  ·  3تعليقات

Symyon picture Symyon  ·  5تعليقات

makarsky picture makarsky  ·  3تعليقات