Hey @Tim Considine ,
The error indicates that you have something trying to access Purchases
before calling .setup()
This could be a request to .getPurchaserInfo()
or something like that.
I’m not a Flutter dev myself, but maybe this sample app helps? https://github.com/RevenueCat/purchases-flutter/tree/main/revenuecat_examples/MagicWeather
@Gandalf I’m not 100% sure, because it’s been such a long time since I was looking at this, but the most likely culprit I landed on was some kind of bizarre conflict with the isolate_handler package. I was using this in my app in order to be able to use plugins from an isolate. I can’t remember why or how I narrowed it down to that possibly being the cause. I would be interested to know if you are also using this package?
I have actually spent the last few weeks updating to flutter 3.7, which now natively supports using plugins in isolates, which means I can remove dependency on isolate_handler. Hopefully now I can remove this workaround.
@James Allen Thank you for your reply, but it has been a long time since I “fixed” this issue. Unfortunately I don’t remember what I did either. Sorry.
Well, I don’t know but I suspect the earlier crash somehow corrupted the appuserID.
So I set it specifically before calling Purchases.setup, and shop page now opens and retrieves data.
Phew.
Worrying though if this happens in production through some app crash. Better make sure the testing regime covers everything !
OK, that was short lived.
Overnight the same error message has come back when starting the app on actual iPhone via cable.
Not aware of any relevant code changes since last working version.
Thoughts ?
Problem persists after `flutter clean` and `flutter pub get`
How is this marked as resolved?
I’ve the same problem as @James Allen.
I had a working app and now, after updating everything, I get this error right after running the app.
Did you find the problem and solution @James Allen ? Or just this horrible workaround?
Would be great if the revenue cat team, who actually know the changes made, could point us somewhere. Right now, I’ll have to inspect the entire code and re-learn the plugin.
@Tim Considine did you get to the bottom of this? I have the exact same problem, except the only change I made was upgrading my app from flutter 1.22.6 to 2.5.2, and updating the purchases_flutter package to the latest. Now all of a sudden I’m getting the “There is no singleton instance” error on both Android and iPhone as soon as I try to get purchase info. Did you also start getting the error after upgrading the package?
I’m initialising it before I use the library in any way:
import 'package:purchases_flutter/purchases_flutter.dart' as revenuecat; // Using alias to avoid namespace clash with Redux package
try {
// Initialise billing (Revenue Cat)
// if(kDebugMode) {
// await revenuecat.Purchases.setDebugLogsEnabled(true);
// }
await revenuecat.Purchases.setup(REVENUE_CAT_API_KEY);
}
catch(e, st) {
debugPrint("Error initialising revenue cat: $e");
}
There is no error when calling Purchases.setup. I’ve also tried moving the initialisation code to main, before flutter even runs, and I still get the error:
import 'package:purchases_flutter/purchases_flutter.dart' as revenuecat; // Using alias to avoid namespace clash with Redux package
void main() async {
try {
// Initialise billing (Revenue Cat)
await revenuecat.Purchases.setup(REVENUE_CAT_API_KEY);
}
catch(e, st) {
debugPrint("Error initialising revenue cat: $e");
}
runApp(ChronicInsightsApp());
}
Here is the error:
PlatformException(error, 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, null, 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
I/flutter ( 9048): at com.revenuecat.purchases.Purchases$Companion.getSharedInstance(Purchases.kt:1760)
I/flutter ( 9048): at com.revenuecat.purchases.hybridcommon.CommonKt.getPurchaserInfo(common.kt:269)
I/flutter ( 9048): at com.revenuecat.purchases_flutter.PurchasesFlutterPlugin.getPurchaserInfo(PurchasesFlutterPlugin.java:453)
I/flutter ( 9048): at com.revenuecat.purchases_flutter.PurchasesFlutterPlugin.onMethodCall(PurchasesFlutterPlugin.java:207)
I/flutter ( 9048): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233)
Any advise would be welcome
Just to add some more info here. It turns out that this error is being thrown before my app even gets a chance to call Purchases.setup(apiKey). I’ve added these log statements:
try {
// Initialise billing (Revenue Cat)
if(kDebugMode) {
await revenuecat.Purchases.setDebugLogsEnabled(true);
}
Fimber.i("Initialising revenue cat...");
await revenuecat.Purchases.setup(REVENUE_CAT_API_KEY);
Fimber.i("Revenue cat init complete");
}
catch(e, st) {
Fimber.e("Error initialising revenue cat", ex: e, stacktrace: st);
}
And here’s the full console output. As you can see, the error is thrown before you see “Initialising revenue cat”. This is happening despite the fact that I’m running this in main, *before the flutter app even starts*. So, something is trying to access the Purchases singleton instance, and it isn’t me - I’m assuming it’s the revenue cat package itself? I’m going to try and downgrade to the package version I was using earlier because it seems to me that there is something really broken here…
Launching lib\main.dart on Pixel in debug mode...
Running Gradle task 'assembleDebug'...
√ Built build\app\outputs\flutter-apk\app-debug.apk.
Installing build\app\outputs\flutter-apk\app.apk...
W/FlutterActivityAndFragmentDelegate(10936): A splash screen was provided to Flutter, but this is deprecated. See flutter.dev/go/android-splash-migration for migration steps.
Debug service listening on ws://127.0.0.1:55414/OLoDsX-LoyQ=/ws
Syncing files to device Pixel...
E/MethodChannel#purchases_flutter(10936): Failed to handle method call
E/MethodChannel#purchases_flutter(10936): 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
E/MethodChannel#purchases_flutter(10936): at com.revenuecat.purchases.Purchases$Companion.getSharedInstance(Purchases.kt:1760)
E/MethodChannel#purchases_flutter(10936): at com.revenuecat.purchases.hybridcommon.CommonKt.getPurchaserInfo(common.kt:269)
E/MethodChannel#purchases_flutter(10936): at com.revenuecat.purchases_flutter.PurchasesFlutterPlugin.getPurchaserInfo(PurchasesFlutterPlugin.java:453)
E/MethodChannel#purchases_flutter(10936): at com.revenuecat.purchases_flutter.PurchasesFlutterPlugin.onMethodCall(PurchasesFlutterPlugin.java:207)
E/MethodChannel#purchases_flutter(10936): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233)
E/MethodChannel#purchases_flutter(10936): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:84)
E/MethodChannel#purchases_flutter(10936): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:865)
E/MethodChannel#purchases_flutter(10936): at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#purchases_flutter(10936): at android.os.MessageQueue.next(MessageQueue.java:336)
E/MethodChannel#purchases_flutter(10936): at android.os.Looper.loop(Looper.java:174)
E/MethodChannel#purchases_flutter(10936): at android.app.ActivityThread.main(ActivityThread.java:7356)
E/MethodChannel#purchases_flutter(10936): at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#purchases_flutter(10936): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
E/MethodChannel#purchases_flutter(10936): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
I/flutter (10936): 2021-10-14T11:28:30.787573 I _createInitialiseApp.<ac>: Set locale en_GB
I/flutter (10936): 2021-10-14T11:28:30.830641 E _createQueryEntitlements.<ac>: Error querying entitlements: PlatformException(error, 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, null, 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
I/flutter (10936): at com.revenuecat.purchases.Purchases$Companion.getSharedInstance(Purchases.kt:1760)
I/flutter (10936): at com.revenuecat.purchases.hybridcommon.CommonKt.getPurchaserInfo(common.kt:269)
I/flutter (10936): at com.revenuecat.purchases_flutter.PurchasesFlutterPlugin.getPurchaserInfo(PurchasesFlutterPlugin.java:453)
I/flutter (10936): at com.revenuecat.purchases_flutter.PurchasesFlutterPlugin.onMethodCall(PurchasesFlutterPlugin.java:207)
I/flutter (10936): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233)
I/flutter (10936): at io.flutter.embedding.engine.dart.Dar
I/flutter (10936): 2021-10-14T11:28:30.838256 I _createInitialiseApp.<ac>: Initialising revenue cat...
D/rPurchases] - DEBUG(10936): ℹ️ Debug logging enabled
D/uPurchases] - DEBUG(10936): ℹ️ SDK Version - 4.3.1
D/Purchases] - DEBUG(10936): 👤 Initial App User ID - null
D/nPurchases] - DEBUG(10936): 👤 Identifying App User ID: $RCAnonymousID:----------------------------
D/-Purchases] - DEBUG(10936): ℹ️ Deleting old synced subscriber attributes that don't belong to $RCAnonymousID:--------------------------------
D/-Purchases] - DEBUG(10936): ℹ️ App foregrounded
D/EPurchases] - DEBUG(10936): ℹ️ PurchaserInfo cache is stale, updating from network in foreground.
D/lPurchases] - DEBUG(10936): ℹ️ Offerings cache is stale, updating from network in foreground
D/sPurchases] - DEBUG(10936): 😻 Offerings updated from network.
D/UPurchases] - DEBUG(10936): ℹ️ Skipping updating pending purchase queue since BillingClient is not connected yet.
D/aPurchases] - DEBUG(10936): ℹ️ No subscriber attributes to synchronize.
D/1Purchases] - DEBUG(10936): ℹ️ Listener set
D/iPurchases] - DEBUG(10936): ℹ️ Sending latest PurchaserInfo to listener.
D/ Purchases] - DEBUG(10936): ℹ️ Starting connection for com.android.billingclient.api.BillingClientImpl@8a84bdf
D/nPurchases] - DEBUG(10936): ℹ️ Billing Service Setup finished for com.android.billingclient.api.BillingClientImpl@8a84bdf
D/uPurchases] - DEBUG(10936): ℹ️ Updating pending purchase queue
I/flutter (10936): 2021-10-14T11:28:31.103731 I _createInitialiseApp.<ac>: Revenue cat init complete
W/chronicinsight(10936): Accessing hidden method Lsun/misc/Unsafe;->getUnsafe()Lsun/misc/Unsafe; (greylist,core-platform-api, linking, allowed)
W/chronicinsight(10936): Accessing hidden method Lsun/misc/Unsafe;->objectFieldOffset(Ljava/lang/reflect/Field;)J (greylist,core-platform-api, linking, allowed)
W/chronicinsight(10936): Accessing hidden method Lsun/misc/Unsafe;->compareAndSwapObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z (greylist, linking, allowed)
W/chronicinsight(10936): Accessing hidden method Lsun/misc/Unsafe;->putObject(Ljava/lang/Object;JLjava/lang/Object;)V (greylist, linking, allowed)
D/OPurchases] - DEBUG(10936): ℹ️ API request started: GET /subscribers/%24RCAnonymousID%----------------------------
D/rPurchases] - DEBUG(10936): ℹ️ API request completed with status: GET /subscribers/%24RCAnonymousID%---------------------------------- 304
D/tPurchases] - DEBUG(10936): ℹ️ PurchaserInfo updated, sending to listener.
D/4Purchases] - DEBUG(10936): ℹ️ No cached Offerings, fetching from network
D/tPurchases] - DEBUG(10936): ℹ️ Vending PurchaserInfo from cache.
D/tPurchases] - DEBUG(10936): ℹ️ Checking if cache is stale AppInBackground false
D/mPurchases] - DEBUG(10936): ℹ️ API request started: GET /subscribers/%24RCAnonymousID%3-------------------------------/offerings
D/Purchases] - DEBUG(10936): ℹ️ API request completed with status: GET /subscribers/%24RCAnonymousID%----------------------------/offerings 304
D/rPurchases] - DEBUG(10936): ℹ️ Requesting products from the store with identifiers: rc_subscription_monthly, rc_subscription_annual
D/6Purchases] - DEBUG(10936): ℹ️ Requesting products from the store with identifiers: rc_subscription_monthly, rc_subscription_annual
D/1Purchases] - DEBUG(10936): ℹ️ Querying purchases
D/ePurchases] - DEBUG(10936): ℹ️ Cleaning previously sent tokens
D/cPurchases] - DEBUG(10936): ℹ️ Tokens already posted: >]
D/sPurchases] - DEBUG(10936): ℹ️ Saving tokens l]
D/kPurchases] - DEBUG(10936): ℹ️ Tokens already posted: a]
D/sPurchases] - DEBUG(10936): ℹ️ Products request finished for rc_subscription_monthly, rc_subscription_annual
D/ Purchases] - DEBUG(10936): ℹ️ Products request finished for rc_subscription_monthly, rc_subscription_annual
D/ Purchases] - DEBUG(10936): 💰 Retrieved skuDetailsList: SkuDetails: ---------------------------
Okay, downgrading the purchases_flutter package to the version I was using previously has NOT resolved the problem. So now I’m totally stumped.
For others who may encounter this issue, I have worked around the problem by adding additional calls to Purchases.setup before any time I use any Purchases method.
I don’t know why this problem started happening even though I haven’t changed the parts of my code which use Purchases for over a year. It may be related to my upgrading my app to flutter 2 and dart null safety, but it may not.
I don’t know why my first call to Purchases.setup on app initialisation doesn’t seem to work anymore.
I don’t know why the ‘There is no singleton instance’ seems to be thrown before my app even starts, and what’s even more strange, I don’t know how adding additional calls to Purchases.setup AFTER my app starts seems to stop the error being thrown.
I have given up trying to understand this and just filing it under ‘weird, random and unexplained error’.