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

Canceling subscription crashes app in production #1207

Open
11 tasks done
TijlIvens opened this issue Nov 12, 2024 · 3 comments
Open
11 tasks done

Canceling subscription crashes app in production #1207

TijlIvens opened this issue Nov 12, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@TijlIvens
Copy link

‼️ 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
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.24.4, on macOS 14.5 23F79 darwin-arm64, locale en-BE)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 16.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2023.1)
[✓] VS Code (version 1.95.0)
[✓] Connected device (5 available)
[✓] Network resources

• No issues found!
  • Version of purchases-flutter
    8.2.1
  • Testing device version e.g.: iOS 15.5, Android API 30, etc.
    iOS 17.7
  • How often the issue occurs- every one of your customers is impacted? Only in dev?
    Only happens in production builds with real subscriptions. On all tested devices.
    Never with a sandbox environment.
  • Debug logs that reproduce the issue
#0	(null) in _assertionFailure(_:_:file:line:flags:) ()
#1	0x000000010056c3fc in closure #1 in variable initialization expression of static FatalErrorUtil.defaultFatalErrorClosure at /Users/stijl/dev/receptenvansandra_app/ios/Pods/PurchasesHybridCommon/ios/PurchasesHybridCommon/PurchasesHybridCommon/FatalErrorUtil.swift:15
#2	0x000000010056c3fc in fatalError(_:file:line:) at /Users/stijl/dev/receptenvansandra_app/ios/Pods/PurchasesHybridCommon/ios/PurchasesHybridCommon/PurchasesHybridCommon/FatalErrorUtil.swift:27
#3	0x000000010056c3fc in static CommonFunctionality.sharedInstance.getter at /Users/stijl/dev/receptenvansandra_app/ios/Pods/PurchasesHybridCommon/ios/PurchasesHybridCommon/PurchasesHybridCommon/CommonFunctionality.swift:21
#4	0x000000010056c3fc in static CommonFunctionality.customerInfo(fetchPolicy:completion:) ()
#5	0x000000010056c3fc in specialized static CommonFunctionality.customerInfo(completion:) at /Users/stijl/dev/receptenvansandra_app/ios/Pods/PurchasesHybridCommon/ios/PurchasesHybridCommon/PurchasesHybridCommon/CommonFunctionality.swift:380
#6	(null) in @objc static CommonFunctionality.restorePurchases(completion:) ()
#7	0x0000000100dae150 in -[PurchasesFlutterPlugin getCustomerInfoWithResult:] at /Users/stijl/.pub-cache/hosted/pub.dev/purchases_flutter-8.2.1/ios/Classes/PurchasesFlutterPlugin.m:373
#8	0x0000000100dac974 in -[PurchasesFlutterPlugin handleMethodCall:result:] at /Users/stijl/.pub-cache/hosted/pub.dev/purchases_flutter-8.2.1/ios/Classes/PurchasesFlutterPlugin.m:104
#9	0x0000000103fb770c in __45-[FlutterMethodChannel setMethodCallHandler:]_block_invoke ()
#10	0x000000010392ae38 in invocation function for block in flutter::PlatformMessageHandlerIos::HandlePlatformMessage(std::_fl::unique_ptr<flutter::PlatformMessage, std::_fl::default_delete<flutter::PlatformMessage>>) ()

  • Steps to reproduce, with a description of expected vs. actual behavior
    In a production environment
    Load subscriptions in the app
    Click on a subscription
    Native popup will open
    Close subscription popu
    App crashes

Describe the bug

The app will crash on iOS when you close the native subscriptions popup of apple. Only in production.

Additional context

The error shows an error that the purchases SDK is not configured. But The subscriptions can be fetched correctly from revenueCat. No issues when doing this in a sandox.

@TijlIvens TijlIvens added the bug Something isn't working label Nov 12, 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!

@HaleyRevcat
Copy link

Hi, if you just released your app on the App Store, then this could be due to products needing ~24 hours to propagate after release. If it has been longer than that, can you make sure that when your app launches you are calling configure right away? Such errors occur if methods of the SDK are attempting to be accessed without initializing it first. Could you share the following:

  • The code snippet where you are calling configure()
  • The code snippet of how you are handling purchases and cancellations

@TijlIvens
Copy link
Author

Hey we have this function to set revenueCat

Future<void> configureRevenueCat(String? customerId) async {
  if (kIsWeb || customerId == null) {
    return;
  }
  try {
    await Purchases.setLogLevel(LogLevel.info);

    await Purchases.configure(
      PurchasesConfiguration(
        Platform.isIOS ? Env.revenueCatAppleApiKey : Env.revenueCatGoogleApiKey,
      )..appUserID = customerId,
    );
  } on Exception catch (e) {
    log('Error configuring RevenueCat: $e');
  }
}

Future<void> setRevenueCatUser(ConsumerProfileState? profile) async {
  try {
    if (kIsWeb) {
      return;
    }
    if (profile == null || profile.subscriptionId == null) {
      return;
    }

    await configureRevenueCat(profile.subscriptionId);

    await Purchases.logIn(profile.subscriptionId!);
    await Purchases.setEmail(profile.email);
    await Purchases.setDisplayName('${profile.firstname} ${profile.lastname}');
    await Purchases.setPhoneNumber(profile.phoneNumber?.toString() ?? '');
  } on Exception catch (e) {
    log('Error setting RevenueCat user: $e');
  }
}

The setRevenueCatUser function is called in the main function before the runApp function.
It is also called after a user logs in or creates a new account. So we set the config to the correct user.
I'm sure thePurchases.configure has run because otherwise the list of offerings wouldn't be able to load in.
The products are now almost a week live on production.

This is the function that is called when an offering is selected and the users presses the buy button:

  Future<void> onBuySubscriptionPress() async {
      final selectedProduct = offeringResult.products.firstWhereOrNull(
        (element) => element.product.identifier == activeSubscriptionId.value,
      );
      if (selectedProduct == null) {
        return;
      }

      try {
        final customerInfo =
            await Purchases.purchaseStoreProduct(selectedProduct.product);
        if (customerInfo.entitlements.all['recipe-subscription']!.isActive) {
          await router.replaceAll([const BuySubscriptionConfirmationRoute()]);
        }
      } on PlatformException catch (e) {
        final errorCode = PurchasesErrorHelper.getErrorCode(e);
        if (errorCode != PurchasesErrorCode.purchaseCancelledError) {
          showErrorMessage(
            scaffoldMessenger,
            description: LocaleKeys
                .buySubscription_messages_activate_subscription_error
                .tr(),
          );
        }
      }

      return;
    }

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

3 participants