Question

Flutter Paywall - There is no singleton instance

  • 8 June 2024
  • 1 reply
  • 46 views

Badge +3

I have a Flutter app using last version of RevenueCat libs (purchases_flutter and purchases_ui_flutter, both at 6.29.2).

 

The Purchases instance is configured during app initialization:

Future<void> setupRevenueCatSDK() async {
await Purchases.setLogLevel(LogLevel.debug);
late PurchasesConfiguration configuration;

if (Platform.isAndroid) {
configuration = PurchasesConfiguration("XXX");
} else if (Platform.isIOS) {
configuration = PurchasesConfiguration("XXX");
}

await Purchases.configure(configuration);

logger.d("RevenueCat / Purchases configured ${configuration.appUserID}");
}


void main() async {
WidgetsFlutterBinding.ensureInitialized();

// ...

await setupRevenueCatSDK();

// ... runApp
}

 

Then I call the UI lib to open the Paywall, after the user taps a button.

response = await RevenueCatUI.presentPaywall()

 

This flow works well for all devices I could test (both iOS and Android) and I had many multiple transactions from other users. Still, I'm seeing dozens of multiple crashes on Crashlytics:

Fatal Exception: z5.I: 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(:11)
at com.revenuecat.purchases.ui.revenuecatui.data.PurchasesImpl.<init>(SourceFile:4)
at com.revenuecat.purchases.ui.revenuecatui.data.PaywallViewModelImpl.<init>(SourceFile:1)
at com.revenuecat.purchases.ui.revenuecatui.data.PaywallViewModelFactory.create(SourceFile:8)
at androidx.lifecycle.H$b.create(SourceFile:4)
at com.revenuecat.purchases.ui.revenuecatui.data.PaywallViewModelFactory.create(SourceFile:1)
at androidx.lifecycle.H.b(:60)
at androidx.lifecycle.H.a(:28)
at g1.b.a(:44)
at g1.b.b(:66)
at com.revenuecat.purchases.ui.revenuecatui.InternalPaywallKt.getPaywallViewModel(:127)
at com.revenuecat.purchases.ui.revenuecatui.InternalPaywallKt.InternalPaywall(:104)
at com.revenuecat.purchases.ui.revenuecatui.PaywallKt.Paywall(:59)
at com.revenuecat.purchases.ui.revenuecatui.activity.PaywallActivity$onCreate$1$1$1.invoke(SourceFile:34)
at com.revenuecat.purchases.ui.revenuecatui.activity.PaywallActivity$onCreate$1$1$1.invoke(SourceFile:1)
at M.b.b(:49)
at M.b.invoke(SourceFile:2)
at androidx.compose.material3.D$d$a$a.invoke(SourceFile:14)
at androidx.compose.material3.D$d$a$a.invoke(SourceFile:1)
at M.b.a(:49)
at M.b.invoke(SourceFile:1)
at i0.w$g.invoke(SourceFile:5)
at i0.w$g.invoke(SourceFile:1)
at M.b.a(:49)
at M.b.invoke(SourceFile:1)
at F.c.b(:22)
at F.m.q0(:146)
at F.m.k0(:18)
at F.r.j(:17)
at F.C0.a(:34)
at F.m$b.a(:16)
at F.r.p(:15)
at i0.w.D(:12)
at i0.w.B(:40)
at i0.w.C(:58)
at i0.w.A(:128)
at i0.w$c.p(:7)
at androidx.compose.material3.D$d$a.invoke(SourceFile:118)
at androidx.compose.material3.D$d$a.invoke(SourceFile:1)
at i0.C$a.b(:48)
at i0.w$d$a.b(:9)
at k0.K$b$b.invoke(SourceFile:4)
at k0.K$b$b.invoke(SourceFile:1)
at O.h$a.d(:69)
at O.w$a.g(:60)
at O.w.n(:34)
at k0.g0.h(:17)
at k0.g0.d(:26)
at k0.K$b.T(:94)
at k0.K$b.z1(:144)
at k0.v.W0(:21)
at i0.N.d0()
at i0.N$a.o(:32)
at k0.K$b$c.invoke(SourceFile:3)
at k0.K$b$c.invoke(SourceFile:1)
at O.h$a.d(:69)
at O.w$a.g(:60)
at O.w.n(:34)
at k0.g0.h(:17)
at k0.g0.b(:26)
at k0.K$b.A1(:87)
at k0.K$b.W0(:94)
at i0.N.d0()
at i0.N$a.o(:32)
at i0.N$a.p(:7)
at androidx.compose.foundation.layout.d.g(:44)
at androidx.compose.foundation.layout.d.c()
at androidx.compose.foundation.layout.d$c$b.invoke(SourceFile:2)
at androidx.compose.foundation.layout.d$c$b.invoke(SourceFile:1)
at i0.C$a.b(:48)
at k0.K$b$b.invoke(SourceFile:4)
at k0.K$b$b.invoke(SourceFile:1)
at O.h$a.d(:69)
at O.w$a.g(:60)
at O.w.n(:34)
at k0.g0.h(:17)
at k0.g0.d(:26)
at k0.K$b.T(:94)
at k0.K$b.z1(:144)
at k0.v.W0(:21)
at i0.N.d0()
at i0.N$a.y(:40)
at i0.N$a.z(:21)
at androidx.compose.ui.graphics.f$b.invoke(SourceFile:2)
at androidx.compose.ui.graphics.f$b.invoke(SourceFile:1)
at i0.C$a.b(:48)
at k0.B.W0(:57)
at i0.N.d0()
at i0.N$a.A(:36)
at k0.K$b$c.invoke(SourceFile:4)
at k0.K$b$c.invoke(SourceFile:1)
at O.h$a.d(:69)
at O.w$a.g(:60)
at O.w.n(:34)
at k0.g0.h(:17)
at k0.g0.b(:26)
at k0.K$b.A1(:87)
at k0.K$b.W0(:94)
at i0.N.d0()
at i0.N$a.u(:107)
at i0.N$a.v(:21)
at i0.S$b.invoke(SourceFile:2)
at i0.S$b.invoke(SourceFile:1)
at i0.C$a.b(:48)
at k0.K$b$b.invoke(SourceFile:4)
at k0.K$b$b.invoke(SourceFile:1)
at O.h$a.d(:69)
at O.w$a.g(:60)
at O.w.n(:34)
at k0.g0.h(:17)
at k0.g0.d(:26)
at k0.K$b.T(:94)
at k0.K$b.z1(:144)
at k0.v.W0(:21)
at i0.N.d0()
at i0.N$a.o(:32)
at k0.K$b$c.invoke(SourceFile:3)
at k0.K$b$c.invoke(SourceFile:1)
at O.h$a.d(:69)
at O.w$a.g(:60)
at O.w.n(:34)
at k0.g0.h(:17)
at k0.g0.b(:26)
at k0.K$b.A1(:87)
at k0.K$b.W0(:94)
at i0.N.d0()
at i0.N$a.q(:103)
at i0.N$a.r(:7)
at k0.F.U0(:71)
at k0.P.u(:123)
at k0.P.b()
at k0.P.o(:75)
at androidx.compose.ui.platform.AndroidComposeView.onLayout(:4)
at android.view.View.layout(View.java:24396)
at android.view.ViewGroup.layout(ViewGroup.java:6509)
at androidx.compose.ui.platform.a.internalOnLayout$ui_release(:27)
at androidx.compose.ui.platform.a.onLayout()
at android.view.View.layout(View.java:24396)
at android.view.ViewGroup.layout(ViewGroup.java:6509)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:353)
at android.widget.FrameLayout.onLayout(FrameLayout.java:279)
at android.view.View.layout(View.java:24396)
at android.view.ViewGroup.layout(ViewGroup.java:6509)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1872)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1694)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1591)
at android.view.View.layout(View.java:24396)
at android.view.ViewGroup.layout(ViewGroup.java:6509)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:353)
at android.widget.FrameLayout.onLayout(FrameLayout.java:279)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:888)
at android.view.View.layout(View.java:24396)
at android.view.ViewGroup.layout(ViewGroup.java:6509)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:4461)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3819)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2725)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9812)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1505)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1513)
at android.view.Choreographer.doCallbacks(Choreographer.java:1128)
at android.view.Choreographer.doFrame(Choreographer.java:1042)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1481)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:211)
at android.os.Looper.loop(Looper.java:300)
at android.app.ActivityThread.main(ActivityThread.java:8503)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:561)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:954)

 

The interesting part is that those errors are raised right after opening the app, without user interaction (Crashlytics displays as "< 1 second crash" -- see screenshots).

 

What I'm I missing?

 


This post has been closed for comments

1 reply

Userlevel 4
Badge +8

Hey, I see this is currently being investigated in a GitHub issue, so we’ll continue replying there.