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

java.lang.IllegalStateException: Reply already submitted casing app to crash only android devices #1216

Open
7 of 11 tasks
TOZXII opened this issue Dec 1, 2024 · 3 comments
Open
7 of 11 tasks
Labels
bug Something isn't working

Comments

@TOZXII
Copy link

TOZXII commented Dec 1, 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
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.24.3, on macOS 15.1 24B83 darwin-arm64, locale en-OM)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 16.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.1)
[✓] VS Code (version 1.95.0)
[✓] Connected device (6 available)
[✓] Network resources

• No issues found!
  • Version of purchases-flutter 8.2.1 and purchases_ui_flutter 8.2.1
  • 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? 4% of my users affected (crash the application)
  • 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.)

stacktraces from sentry:

r7.c$g in a at line 36
c8.i$a$a in a at line 15
com.revenuecat.purchases_ui_flutter.PurchasesUiFlutterPlugin$presentPaywall$2 in onPaywallResult at line 2
com.revenuecat.purchases.hybridcommon.ui.PaywallFragment in onActivityResult at line 3
com.revenuecat.purchases.hybridcommon.ui.PaywallFragment in onActivityResult at line 1
d.e in d at line 23
d.e in b at line 25
androidx.activity.h in onActivityResult at line 3
androidx.fragment.app.w in onActivityResult at line 6
io.flutter.embedding.android.h in onActivityResult at line 1
android.app.Activity in dispatchActivityResult at line 8930
android.app.ActivityThread in deliverResults at line 5595
android.app.ActivityThread in handleSendResult at line 5641
android.app.servertransaction.ActivityResultItem in execute at line 67
android.app.servertransaction.ActivityTransactionItem in execute at line 45
android.app.servertransaction.TransactionExecutor in executeCallbacks at line 135
android.app.servertransaction.TransactionExecutor in execute at line 95
android.app.ActivityThread$H in handleMessage at line 2440
android.os.Handler in dispatchMessage at line 106
android.os.Looper in loopOnce at line 211
android.os.Looper in loop at line 300
android.app.ActivityThread in main at line 8315
java.lang.reflect.Method in invoke
com.android.internal.os.RuntimeInit$MethodAndArgsCaller in run at line 581
com.android.internal.os.ZygoteInit in main at line 1028

From google play console:

Exception java.lang.RuntimeException:
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3709)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:3866)
  at android.app.servertransaction.LaunchActivityItem.execute (LaunchActivityItem.java:103)
  at android.app.servertransaction.TransactionExecutor.executeCallbacks (TransactionExecutor.java:135)
  at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:95)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2281)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loopOnce (Looper.java:223)
  at android.os.Looper.loop (Looper.java:317)
  at android.app.ActivityThread.main (ActivityThread.java:7942)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:568)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1045)
Caused by l8.h0: There is no singleton instance. Make sure you configure Purchases before trying to get the default instance. More info here: https://errors.rev.cat/configuring-sdk
  at com.revenuecat.purchases.Purchases$Companion.getSharedInstance (Purchases.kt:887)
  at com.revenuecat.purchases.ui.revenuecatui.helpers.HelperFunctionsKt.shouldDisplayPaywall (HelperFunctions.kt:48)
  at com.revenuecat.purchases.ui.revenuecatui.activity.PaywallActivityLauncher.launchIfNeeded (PaywallActivityLauncher.kt:115)
  at com.revenuecat.purchases.ui.revenuecatui.activity.PaywallActivityLauncher.launchIfNeeded$default (PaywallActivityLauncher.kt:107)
  at com.revenuecat.purchases.hybridcommon.ui.PaywallFragment.launchPaywallIfNeeded (PaywallFragment.kt:135)
  at com.revenuecat.purchases.hybridcommon.ui.PaywallFragment.onCreate (PaywallFragment.kt:104)
  at androidx.fragment.app.Fragment.performCreate (Fragment.java:3095)
  at androidx.fragment.app.FragmentStateManager.create (FragmentStateManager.java:516)
  at androidx.fragment.app.FragmentStateManager.moveToExpectedState (FragmentStateManager.java:274)
  at androidx.fragment.app.FragmentStore.moveToExpectedState (FragmentStore.java:114)
  at androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:1614)
  at androidx.fragment.app.FragmentManager.dispatchStateChange (FragmentManager.java:3198)
  at androidx.fragment.app.FragmentManager.dispatchCreate (FragmentManager.java:3105)
  at androidx.fragment.app.FragmentController.dispatchCreate (FragmentController.java:252)
  at androidx.fragment.app.FragmentActivity.onCreate (FragmentActivity.java:219)
  at io.flutter.embedding.android.FlutterFragmentActivity.onCreate (FlutterFragmentActivity.java:380)
  at android.app.Activity.performCreate (Activity.java:8115)
  at android.app.Activity.performCreate (Activity.java:8095)
  at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1329)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3682)

Describe the bug

This bug causes the application to [crash] on Android devices. About 4% of Android users have this issue.
Everything from my end is correct {I will provide the code}, I made sure the configure Purchases is done right but still the issue happens no matter what I do.

Additional context

class StoreConfig {
  final Store store;
  final String apiKey;
  static StoreConfig? _instance;

  factory StoreConfig({required Store store, required String apiKey}) {
    _instance ??= StoreConfig._internal(store, apiKey);
    return _instance!;
  }

  StoreConfig._internal(this.store, this.apiKey);

  static StoreConfig get instance {
    return _instance!;
  }

  static bool isForAppleStore() => instance.store == Store.appStore;

  static bool isForGooglePlay() => instance.store == Store.playStore;

  static StoreConfig init() {
    if (Platform.isAndroid) {
      return StoreConfig(store: Store.playStore, apiKey: googleApiKey);
    } else {
      return StoreConfig(store: Store.appStore, apiKey: appleApiKey);
    }
  }
}

Future<bool> configureSDK() async {
  try {
    await Purchases.setLogLevel(LogLevel.debug);
    PurchasesConfiguration configuration =
        PurchasesConfiguration(StoreConfig.instance.apiKey);

    await Purchases.configure(configuration);
    return true;
  } catch (e) {
    Sentry.captureException(e);
    return false;
  }
}

Future<bool> presentPaywallIfNeeded(WidgetRef ref) async {
  try {
    // check if purchase id config is set
    if (!(await Purchases.isConfigured)) {
      await configureSDK();
    }

    if (!(await Purchases.isConfigured)) {
      Sentry.captureException(
          'Failed to configure RevenueCat SDK (presentPaywallIfNeeded Fn)');
      return false;
    }

    final paywallResult = await RevenueCatUI.presentPaywallIfNeeded(
      entitlmentID,
      displayCloseButton: true,
    );

    // Refresh the subscription status after presenting the paywall
    await ref.read(subscriptionProvider.notifier).refreshSubscriptionStatus();
    // Return true if the user is now subscribed
    return ref.read(subscriptionProvider).isSubscribed;
  } catch (e) {
    // Handle any initialization errors
    // send error to google analytics with log event

    Sentry.captureException(e);

    return false;
  }
}

main.dart

  // Initialize RevenueCat
  StoreConfig.init();
  await configureSDK();

MainActivity.kt

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.android.FlutterFragmentActivity;
class MainActivity: FlutterFragmentActivity()
@TOZXII TOZXII added the bug Something isn't working label Dec 1, 2024
@RCGitBot
Copy link
Contributor

RCGitBot commented Dec 1, 2024

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

@rglanz-rc
Copy link

Hi @TOZXII are you able to reproduce this in a dev environment and get logs?

This is the offending line:

Caused by l8.h0: There is no singleton instance. Make sure you configure Purchases before trying to get the default instance. More info here: https://errors.rev.cat/configuring-sdk

And it indicates that the SDK was not configured (the logs might help us determine why that is)

@jakobhec
Copy link

jakobhec commented Jan 3, 2025

We are encountering the same issue using purchases_ui_flutter and purchases_flutter version 8.4.0. It only happens on Android.

Example stack trace from Firebase Crashlytics:

          Fatal Exception: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=799855538, result=0, data=null} to activity {io.brickmonkey.minifigapp/io.brickmonkey.minifigapp.MainActivity}: java.lang.IllegalStateException: Reply already submitted
       at android.app.ActivityThread.deliverResults(ActivityThread.java:5994)
       at android.app.ActivityThread.handleSendResult(ActivityThread.java:6033)
       at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:67)
       at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
       at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2574)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:226)
       at android.os.Looper.loop(Looper.java:313)
       at android.app.ActivityThread.main(ActivityThread.java:8762)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
          Caused by java.lang.IllegalStateException: Reply already submitted
       at io.flutter.embedding.engine.dart.DartMessenger$Reply.reply(DartMessenger.java:36)
       at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.success(MethodChannel.java:15)
       at com.revenuecat.purchases_ui_flutter.PurchasesUiFlutterPlugin$presentPaywall$2.onPaywallResult(PurchasesUiFlutterPlugin.kt:2)
       at com.revenuecat.purchases.hybridcommon.ui.PaywallFragment.onActivityResult(PaywallFragment.kt:1)
       at com.revenuecat.purchases.hybridcommon.ui.PaywallFragment.onActivityResult(PaywallFragment.kt:2)
       at androidx.activity.result.ActivityResultRegistry.doDispatch(ActivityResultRegistry.kt:31)
       at androidx.activity.result.ActivityResultRegistry.dispatchResult(ActivityResultRegistry.kt:25)
       at androidx.activity.ComponentActivity.onActivityResult(ComponentActivity.kt:3)
       at androidx.fragment.app.FragmentActivity.onActivityResult(FragmentActivity.java:5)
       at io.flutter.embedding.android.FlutterFragmentActivity.onActivityResult(FlutterFragmentActivity.java:1)
       at android.app.Activity.dispatchActivityResult(Activity.java:8951)
       at android.app.ActivityThread.deliverResults(ActivityThread.java:5987)
       at android.app.ActivityThread.handleSendResult(ActivityThread.java:6033)
       at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:67)
       at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
       at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2574)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:226)
       at android.os.Looper.loop(Looper.java:313)
       at android.app.ActivityThread.main(ActivityThread.java:8762)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)

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

4 participants