Question

My app crashes for some users because of Revenuecat SDK

  • 23 November 2023
  • 5 replies
  • 144 views

Badge +4

 

This is the Crash Report I got from the Play Console: 

 

Type

java.lang.OutOfMemoryError
Exception java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
at java.lang.Thread.nativeCreate
at java.lang.Thread.start (Thread.java:976)
at java.util.concurrent.ThreadPoolExecutor.addWorker (ThreadPoolExecutor.java:954)
at java.util.concurrent.ThreadPoolExecutor.ensurePrestart (ThreadPoolExecutor.java:1610)
at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute (ScheduledThreadPoolExecutor.java:351)
at java.util.concurrent.ScheduledThreadPoolExecutor.schedule (ScheduledThreadPoolExecutor.java:569)
at java.util.concurrent.ScheduledThreadPoolExecutor.submit (ScheduledThreadPoolExecutor.java:722)
at java.util.concurrent.Executors$DelegatedExecutorService.submit (Executors.java:705)
at com.revenuecat.purchases.common.Dispatcher.enqueue (Dispatcher.kt:69)
at com.revenuecat.purchases.paywalls.events.PaywallEventsManager.enqueue (PaywallEventsManager.kt:89)
at com.revenuecat.purchases.paywalls.events.PaywallEventsManager.enqueue$default (PaywallEventsManager.kt:88)
at com.revenuecat.purchases.paywalls.events.PaywallEventsManager.flushEvents (PaywallEventsManager.kt:43)
at com.revenuecat.purchases.PurchasesOrchestrator.flushPaywallEvents (PurchasesOrchestrator.kt:1113)
at com.revenuecat.purchases.PurchasesOrchestrator.onAppForegrounded (PurchasesOrchestrator.kt:198)
at com.revenuecat.purchases.AppLifecycleHandler.onStart (AppLifecycleHandler.kt:11)
at androidx.lifecycle.FullLifecycleObserverAdapter.onStateChanged (FullLifecycleObserverAdapter.java:39)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent (LifecycleRegistry.java:360)
at androidx.lifecycle.LifecycleRegistry.addObserver (LifecycleRegistry.java:202)
at com.revenuecat.purchases.PurchasesOrchestrator$2.invoke (PurchasesOrchestrator.kt:154)
at com.revenuecat.purchases.PurchasesOrchestrator$2.invoke (PurchasesOrchestrator.kt:151)
at com.revenuecat.purchases.PurchasesOrchestrator.dispatch (PurchasesOrchestrator.kt:784)
at com.revenuecat.purchases.PurchasesOrchestrator.<init> (PurchasesOrchestrator.kt:151)
at com.revenuecat.purchases.PurchasesOrchestrator.<init> (PurchasesOrchestrator.kt:68)
at com.revenuecat.purchases.PurchasesFactory.createPurchases (PurchasesFactory.kt:245)
at com.revenuecat.purchases.PurchasesFactory.createPurchases$default (PurchasesFactory.kt:58)
at com.revenuecat.purchases.Purchases$Companion.configure (Purchases.kt:852)
at com.revenuecat.purchases.hybridcommon.CommonKt.configure (common.kt:516)
at com.revenuecat.purchases_flutter.PurchasesFlutterPlugin.setupPurchases (PurchasesFlutterPlugin.java:367)
at com.revenuecat.purchases_flutter.PurchasesFlutterPlugin.onMethodCall (PurchasesFlutterPlugin.java:142)
at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage (MethodChannel.java:258)
at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler (DartMessenger.java:295)
at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger (DartMessenger.java:322)
at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run
at android.os.Handler.handleCallback (Handler.java:942)
at android.os.Handler.dispatchMessage (Handler.java:99)
at android.os.Looper.loopOnce (Looper.java:240)
at android.os.Looper.loop (Looper.java:351)
at android.app.ActivityThread.main (ActivityThread.java:8423)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:584)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1013)

I’m trying to reproduce the crash at testing but I can’t get it, however, about 17% of my users got it! 


5 replies

Userlevel 2
Badge +3

Hi @ahmad-4cd8c2, thanks for reporting this! We haven’t been able to reproduce either, but we’re working on some optimizations that might help reduce the chances of this happening https://github.com/RevenueCat/purchases-android/pull/1496. In the meantime, please let us know if you’re able to repro or have access to debug logs. Also, if you have information about in what devices/android versions this is happening could be useful.

Badge +4

Hi @toni-rico 

The crash above happened on:

OnePlus OP516FL1 (OnePlus 10 Pro 5G)

Android 13 (SDK 33)

 

Also the following change is the only one I have made to my code at the last app version, can it be the reason? 

instead of checking for one active entitlement, I now check for two as the following: 

         await Purchases.setLogLevel(LogLevel.debug);
PurchasesConfiguration configuration;
configuration = PurchasesConfiguration("xxxxx")
..appUserID = userDatabase.firebaseId
..observerMode = false;
await Purchases.configure(configuration);
CustomerInfo purchaserInfo = await Purchases.getCustomerInfo();

var isPro = purchaserInfo.entitlements.active.containsKey("Pro");
var isProS = purchaserInfo.entitlements.active.containsKey("Pros");


if(isProS){
var begDate = purchaserInfo.entitlements.all["Pros"]?.originalPurchaseDate;
var expDate = purchaserInfo.entitlements.all["Pros"]?.expirationDate;
await subscribe(Pros);
notifyListeners();
return;
}

else if (isPro) {
var begDate = purchaserInfo.entitlements.all["Pro"]?.originalPurchaseDate;
var expDate = purchaserInfo.entitlements.all["Pro"]?.expirationDate;
await subscribe(Pro);
notifyListeners();
return;
}

 

Before, I was only checking for one entitlement like this: 

var isPro = purchaserInfo.entitlements.active.containsKey("Pro");

 

Is there anything wrong I have done here? 

 

Im still trying to reproduce it on my machine. 

Userlevel 2
Badge +3

Hi @ahmad-4cd8c2

No, that code seems fine. That shouldn’t cause any excess memory usage or anything like that. This crash seems to have happened while creating a secondary thread for some background processing we need to do. This may happen if the app has excessive memory usage.

Is this the only crash like this or do you have other similar Out of memory exception crashes that you can share? Maybe there is something else in your app that’s using a lot of memory? 

Badge +4

@toni-rico 

I finally debugged it and here is the log I got: 

I/[Purchases] - INFO(27252): Purchases instance already set. Did you mean to configure two Purchases objects?
D/[Purchases] - DEBUG(27252): ℹ️ Debug logging enabled
D/[Purchases] - DEBUG(27252): ℹ️ SDK Version - 7.2.4
D/[Purchases] - DEBUG(27252): ℹ️ Package name - ***********
D/[Purchases] - DEBUG(27252): 👤 Initial App User ID - 10211***********
D/[Purchases] - DEBUG(27252): ℹ️ Purchases configured with response verification: DISABLED
D/[Purchases] - DEBUG(27252): 👤 Identifying App User ID: 10211***********
D/[Purchases] - DEBUG(27252): ℹ️ Deleting old synced subscriber attributes that don't belong to 10211***********
D/[Purchases] - DEBUG(27252): ℹ️ App foregrounded
D/[Purchases] - DEBUG(27252): ℹ️ CustomerInfo cache is stale, updating from network in foreground.
D/[Purchases] - DEBUG(27252): Retrieving customer info with policy: FETCH_CURRENT
D/[Purchases] - DEBUG(27252): ℹ️ Updating pending purchase queue
D/[Purchases] - DEBUG(27252): ℹ️ Offerings cache is stale, updating from network in foreground
D/[Purchases] - DEBUG(27252): 😻 Start Offerings update from network.
D/[Purchases] - DEBUG(27252): Request already scheduled with jitter delay, adding existing callbacks to unjittered request with key: BackgroundAwareCallbackCacheKey(cacheKey=[/subscribers/10211***********/offerings], appInBackground=false)
D/[Purchases] - DEBUG(27252): ℹ️ Updating pending purchase queue
D/[Purchases] - DEBUG(27252): ℹ️ No subscriber attributes to synchronize.
D/[Purchases] - DEBUG(27252): ℹ️ Listener set
D/[Purchases] - DEBUG(27252): ℹ️ Sending latest CustomerInfo to listener.
I/System.out(27252): (HTTPLog)-Static: isSBSettingEnabled false
I/System.out(27252): (HTTPLog)-Static: isSBSettingEnabled false
D/[Purchases] - DEBUG(27252): ℹ️ Starting connection for com.android.billingclient.api.BillingClientImpl@5057383
D/[Purchases] - DEBUG(27252): ℹ️ Ending connection for com.android.billingclient.api.BillingClientImpl@5c89da
D/[Purchases] - DEBUG(27252): Retrieving customer info with policy: CACHED_OR_FETCHED
D/[Purchases] - DEBUG(27252): ℹ️ Vending CustomerInfo from cache.
D/[Purchases] - DEBUG(27252): ℹ️ Checking if cache is stale AppInBackground false

W/[Purchases] - WARN(27252): ⚠️ Unable to start a network connection due to a network configuration issue: thread interrupted


D/[Purchases] - DEBUG(27252): API request started: GET /subscribers/10211651731635640/offerings

 

and then Revenuecat returns cached CustomerInfo (old) where the entitlement is marked as “Active” but the expirationDate is in the past (ofc bcz it is not updated after the auto-renewal), and thats exactly what breaks my app code as the comparing: DateTime.now().isBefore(expdate) returns false…..so it keep checking with Revenuecat until a runtime error?! 

 

E/[Purchases] - ERROR(27252): 😿‼️ PurchasesError(code=NetworkError, underlyingErrorMessage=thread interrupted, message='Error performing request.')
E/[Purchases] - ERROR(27252): 🤖‼️ Error fetching offerings - PurchasesError(code=NetworkError, underlyingErrorMessage=thread interrupted, message='Error performing request.')
I/[Purchases] - INFO(27252): Purchases instance already set. Did you mean to configure two Purchases objects?
D/[Purchases] - DEBUG(27252): ℹ️ Debug logging enabled
D/[Purchases] - DEBUG(27252): ℹ️ SDK Version - 7.2.4
D/[Purchases] - DEBUG(27252): ℹ️ Package name - ****************
D/[Purchases] - DEBUG(27252): 👤 Initial App User ID - 1021**********
D/[Purchases] - DEBUG(27252): ℹ️ Purchases configured with response verification: DISABLED

etc.....................

 

Also note that, I only get this error when I launch the code at the start of the app, Only when I close the app from the background and launch it again and Programmatically trigger it. 

 

And I noted that if I triggered Purchases.syncPurchases() + Future.delayed(Duration(seconds: 10))

, it works normally but I can’t wait few seconds at every start of the app.

 

Is there anything i can do to fix it? 

Userlevel 2
Badge +3

Hi @ahmad-4cd8c2, I saw this log a couple of times:

I/[Purchases] - INFO(27252): Purchases instance already set. Did you mean to configure two Purchases objects?

This means you’re calling `Purchases.configure` multiple times, which can have unexpected consequences. `Purchases.configure` should only be called once during the app’s lifetime. Can you try to update to remove that and see if it still happens?

Reply