Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deferred Proration Mode Blocks Execution and Keeps Loader Spinning #1120

Open
5 of 11 tasks
Louna-akkad1 opened this issue Jul 21, 2024 · 11 comments
Open
5 of 11 tasks
Labels
bug Something isn't working

Comments

@Louna-akkad1
Copy link

Louna-akkad1 commented Jul 21, 2024

‼️ Required data ‼️

Do not remove any of the steps from the template below. If a step is not applicable to your issue, please leave that step empty.

There are a lot of things that can contribute to things not working. Having a very basic understanding of your environment will help us understand your issue faster!

Environment

  • Output of flutter doctor
  • Version of purchases-flutter
  • Testing device version e.g.: iOS 15.5, Android API 30, etc.
  • How often the issue occurs- every one of your customers is impacted? Only in dev?
  • Debug logs that reproduce the issue
  • Steps to reproduce, with a description of expected vs. actual behavior
    Other information (e.g. stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, etc.)

Version of purchases-flutter: [6.30.0]
flutter version 3.7.7

error

W/BillingLogger(30245): Unable to log. W/BillingLogger(30245): java.lang.NullPointerException W/BillingLogger(30245): at com.google.android.gms.internal.play_billing.zzbp.<init>(com.android.billingclient:billing@@6.2.1:4) W/BillingLogger(30245): at com.google.android.gms.internal.play_billing.zzdd.zzA(com.android.billingclient:billing@@6.2.1:4) W/BillingLogger(30245): at com.google.android.gms.internal.play_billing.zzdd.zzk(com.android.billingclient:billing@@6.2.1:2) W/BillingLogger(30245): at com.google.android.gms.internal.play_billing.zzgy.zzB(com.android.billingclient:billing@@6.2.1:1) W/BillingLogger(30245): at com.android.billingclient.api.zzcd.zzc(com.android.billingclient:billing@@6.2.1:1) W/BillingLogger(30245): at com.android.billingclient.api.zzj.onReceive(com.android.billingclient:billing@@6.2.1:12) W/BillingLogger(30245): at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0(LoadedApk.java:1911) W/BillingLogger(30245): at android.app.LoadedApk$ReceiverDispatcher$Args.$r8$lambda$gDuJqgxY6Zb-ifyeubKeivTLAwk(Unknown Source:0) W/BillingLogger(30245): at android.app.LoadedApk$ReceiverDispatcher$Args$$ExternalSyntheticLambda0.run(Unknown Source:2) W/BillingLogger(30245): at android.os.Handler.handleCallback(Handler.java:958) W/BillingLogger(30245): at android.os.Handler.dispatchMessage(Handler.java:99) W/BillingLogger(30245): at android.os.Looper.loopOnce(Looper.java:230) W/BillingLogger(30245): at android.os.Looper.loop(Looper.java:319) W/BillingLogger(30245): at android.app.ActivityThread.main(ActivityThread.java:8919) W/BillingLogger(30245): at java.lang.reflect.Method.invoke(Native Method) W/BillingLogger(30245): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578) W/BillingLogger(30245): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103) /[Purchases] - DEBUG(30245): ℹ️ BillingWrapper purchases updated: productIds: [family_yearly_special_subscription], orderId: GPA.3374-6462-8587-48002, purchaseToken: nonmibflhkojipgikaofmedb.AO-J1OyJ-Ng8PVAyho90pHq1tBU8ExJpa8PQHhM3KTWkFqxXjiJsVJcqdCVvjMfhIDg2m_ZQP6WVMBhxieMD3jV0mZ0o6N2SCQ D/[Purchases] - DEBUG(30245): ℹ️ Requesting products from the store with identifiers: family_yearly_special_subscription I/InsetsSourceConsumer(30245): applyRequestedVisibilityToControl: visible=true, type=statusBars, host=com.arabee.family/com.android.billingclient.api.ProxyBillingActivity

Describe the bug

Implement the following code to handle subscription downgrade in google play:


import 'package:flutter/material.dart';
import 'package:purchases_flutter/purchases_flutter.dart';

Future<void> purchaseSubscription(BuildContext context, Package package, String activeSubscriptionId) async {
  try {
    WidgetUtils.showLoading(context);

    // Sync attributes and offerings if needed
    Purchases.syncAttributesAndOfferingsIfNeeded();

    CustomerInfo customerInfo;

    if (activeSubscriptionId.isNotEmpty) {
      print("---------------------+++++++++++++ deferred---------------------+++++++++++++ ");

      customerInfo = await Purchases.purchasePackage(
        package,
        googleProductChangeInfo: GoogleProductChangeInfo(
          activeSubscriptionId,
          prorationMode: GoogleProrationMode.deferred,
        ),
      );

      print("---------------------+++++++++++++ after deferred---------------------+++++++++++++ ");
    } else {
      customerInfo = await Purchases.purchasePackage(package);
    }

    print('---------------------+++++++++++++ payment is done now ---------------------+++++++++++++ ');

    if (customerInfo.activeSubscriptions.isNotEmpty) {
      logPurchase(package.storeProduct.currencyCode, package.storeProduct.price);

      print('purchase-updated: `${package}`');
      await Future.delayed(Duration(seconds: 2));
      WidgetUtils.hideLoading(context);

      Navigator.of(context).pushNamed("/home");
    }
  } on PlatformException catch (e) {
    WidgetUtils.hideLoading(context);
    final errorCode = PurchasesErrorHelper.getErrorCode(e);

    String errorMessage = "An error occurred: ${e.message}";

    if (errorCode == PurchasesErrorCode.purchaseNotAllowedError) {
      errorMessage = 'User not allowed to purchase';
    } else if (errorCode == PurchasesErrorCode.paymentPendingError) {
      errorMessage = 'Payment is pending';
    } else if (errorCode == PurchasesErrorCode.productAlreadyPurchasedError) {
      errorMessage = 'User already subscribed';
    }

    if (errorCode != PurchasesErrorCode.purchaseCancelledError) {
      WidgetUtils.showMessage(context, "Purchase Error", errorMessage);
    }
  }
}

await Purchases.purchasePackage call does not resolve when GoogleProrationMode.deferred is used.
Expected behavior: The await Purchases.purchasePackage call should resolve, allowing subsequent code to execute and the loader to be hidden.

Actual behavior: The await Purchases.purchasePackage call does not resolve, causing the loader to spin indefinitely.

Additional context

in backend im getting notification and the package is downgraded

@Louna-akkad1 Louna-akkad1 added the bug Something isn't working label Jul 21, 2024
@RCGitBot
Copy link
Contributor

👀 We've just linked this issue to our internal tracker and notified the team. Thank you for reporting, we're checking this out!

@Jethro87
Copy link

Thanks for posting this @Louna-akkad1. Does this error reproduce 100% of the time, or is it transient? Also, does this only occur in debug mode? Have you been able to test this in production?

@Louna-akkad1
Copy link
Author

@Jethro87 its reproduce 100% of the time with sandbox with Deferred Proration Mode only other modes work fine
i have not test this in production

@Jethro87
Copy link

@Louna-akkad1 Thanks. Our engineering team is digging into this - can you share more comprehensive debug logs? All logs from when you start your app to when you hit the error would be great.

@ricardo-pixzelle
Copy link

@Jethro87 any news on this issue? Play Store is going to force the billing on updates on the app and we can't use the new library yet

@Jethro87
Copy link

@ricardo-pixzelle Our team can reproduce this error in the sandbox, but the SDK doesn't hang and the purchases go through. Are you seeing this in the sandbox, or also in production? Also, can you share full debug logs?

@yuyangpl
Copy link

yuyangpl commented Sep 6, 2024

’await Purchases.purchasePackage‘ Is suspended, causing subsequent code to fail to execute

@therohansanap
Copy link

@Jethro87 This happens on production as well as sandbox. You are correct that the purchase goes through but this particular future call never completes:

await Purchases.purchaseStoreProduct(
  product,
  googleProductChangeInfo: productChangeInfo,
);

It doesn't throw any error, neither does it completes successfully. Execution cannot move ahead as the future never completes.

@Jethro87
Copy link

@therohansanap Thanks for reporting. Can you reply with full debug logs so our team can further dig into this?

@ricardo-pixzelle
Copy link

Hi @Jethro87 don't know if this helps, this are some logs on the Android app:

image

We are facing this issue when we use the deferred option on Android, in iOS we don't have that problem so the app just stays hanging with that exception

We were using this:

image

We tried this on the 6.30.0 version, but since this didn't worked we reversed to the 5.8 version, but know Play Store needs us to upgrade the billing SDK so we don't know which version to use

@Jethro87
Copy link

@ricardo-pixzelle Apologies for missing this. Thank you for sharing some debug logs. We've since fixed various NullPointerExceptions that have cropped up - is it possible to try the latest version of our SDK? The current latest version is 8.10.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants