Purchases UI Crash
- [x] I have updated Purchases SDK to the latest version
- [x] I have read the Contribution Guidelines
- [x] I have searched the Community
- [x] I have read docs.revenuecat.com
- [x] I have searched for existing Github issues
Describe the bug Prior discussion => https://community.revenuecat.com/sdks-51/kmp-there-is-no-singleton-instance-make-sure-you-configure-purchases-before-trying-to-get-the-default-instance-6952?postid=24026#post24026
I see crashes with new purchases UI. This doesn't happen on every device, but it increased crash rate significantly
- Environment
- Platform: Android
- SDK version: 8.4.0
- OS + version: 12-13-14
- Xcode/Android Studio version:
- Unity version: 6000.0.058f1
- How widespread is the issue. Percentage of devices affected. Don't know. Maybe 1%-5%
- 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.)
Caused by kotlin.UninitializedPropertyAccessException: 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:1055)
at com.revenuecat.purchases.ui.revenuecatui.helpers.HelperFunctionsKt.shouldDisplayPaywall(HelperFunctions.kt:48)
at com.revenuecat.purchases.ui.revenuecatui.activity.PaywallActivityLauncher.launchIfNeeded(PaywallActivityLauncher.kt:171)
at com.revenuecat.purchasesunity.ui.PaywallTrampolineActivity.launchPaywallIfNeeded(PaywallTrampolineActivity.java:63)
at com.revenuecat.purchasesunity.ui.PaywallTrampolineActivity.onCreate(PaywallTrampolineActivity.java:50)
at android.app.Activity.performCreate(Activity.java:8104)
at android.app.Activity.performCreate(Activity.java:8084)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3680)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3867)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:105)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:136)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2279)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7986)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:553)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Additional context
- This happens very early. It’s generally happens in the first few seconds
- I don’t show paywall on game start, so I’m just wondering if any of the android/unity code that automatically tries to show paywall on start.
- I'm suspecting this line is called automatically https://github.com/RevenueCat/purchases-unity/blob/e91cf9704ec97f387ce9ceb6999af9a858729ad4/RevenueCatUI/Plugins/Android/RevenueCatUI.androidlib/src/main/java/com/revenuecat/purchasesunity/ui/PaywallTrampolineActivity.java#L49
👀 We've just linked this issue to our internal tracker and notified the team. Thank you for reporting, we're checking this out!
@cihadturhan , that line does get called automatically in the onCreate of the PaywallTrampolineActivity, but that activity is only created after calling presentPaywallIfNeeded.
It looks like there might be a race condition between your Purchases.configure call and presentPaywall. How are you calling Purchases.configure? For some reason it looks like configure hasn't finished by the time you call presentPaywall
It looks like there might be a race condition between your Purchases.configure call and presentPaywall.
I have suspected that but I couldn't find if this could be a reason.
For some reason it looks like configure hasn't finished by the time you call presentPaywall
Here is how my setup is
- Bootstrap.unity
- Initializes RevenueCat (
purchases.configure) - Initializes Analytics
- Initializes Ads
- Initializes RevenueCat (
- Gameplay.unity (first user with demo gameplay)
- Takes around 30 seconds to finish
- Then, shows a paywall
- Home.unity (subsequent runs)
- Paywall is only shown after user taps (Pro) button
As you can see, I don't have any Paywall shown app open.
Besides, I started checking if revenuecat is configured before showing a paywall as suggested in the community discussion.
public async UniTask<bool> ShowPaywallAsync()
{
var configured = false;
var counter = 0;
while (!configured)
{
await UniTask.Yield();
configured = Purchaser.I.purchases.IsConfigured();
counter++;
}
if (counter > 3)
{
AnalyticsController.LogCustomEvent("paywall_show_slow_configuration", new Dictionary<string, object>
{
{ "frames_waited", counter }
});
}
var result = await PaywallsPresenter.PresentIfNeeded("vip", new PaywallOptions(displayCloseButton: true));
switch (result.Result)
{
case PaywallResultType.Purchased:
return true;
case PaywallResultType.Restored:
UnityEngine.Debug.Log("[RevenueCatUI] Paywall restored purchase.");
return true;
case PaywallResultType.NotPresented:
case PaywallResultType.Cancelled:
return false;
case PaywallResultType.Error:
ShowMessage("Error", "An error occurred while showing the paywall. Please try again later.");
return false;
default:
ShowMessage("Error", "An unknown error occurred. Please try again later.");
return false;
}
}
FYI paywall_show_slow_configuration event is never triggered.