Hi everyone,
We have a Subscription page developed in Flutter that displays 3 Tiers of subscription - LITE, PRO (Monthly & Annual) and ULTRA (Monthly and Annual). RevenueCat’s single paywall only supports a single offering - current. And hence, the way that we’ve configured is that there are 2 offerings - PRO (with its PRO paywall) and Ultra (with its ULTRA paywall).
When the page is loaded, in the initState() - we call:
if (Platform.isAndroid) {
await Purchases.configure(
PurchasesConfiguration("xxx")
..appUserID = userId);
} else if (Platform.isIOS) {
await Purchases.configure(
PurchasesConfiguration("yyyy")
..appUserID = userId);
}
To show 2 different Paywalls, there is a function that gets the respective offerings in initState():
var _offerings = await Purchases.getOfferings();
var _proOffering = await _offerings.getOffering('Pro')!;
var _ultraOffering = await _offerings.getOffering('Ultra')!;
setState(() {
offerings = _offerings;
proOffering = _proOffering;
ultraOffering = _ultraOffering;
});
In order to show the different paywalls, we use a PageView to render the different Paywalls:
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(20, 80, 20, 0),
child: PageView(
controller: pageViewController ??= PageController(
viewportFraction: 0.95,
initialPage: initialPage),
scrollDirection: Axis.horizontal,
children: h
Container(
margin: EdgeInsets.fromLTRB(5, 0, 5, 0),
child: showSystemLitePlan()), // this is a free tier, so it’s a custom widget
showPayWall('PRO'),
showPayWall('ULTRA'),
],
The code for showPayWall is as simple as it gets - as follows:
Widget showPayWall(String tier) {
return Container(
margin: EdgeInsets.fromLTRB(10, 40, 10, 20),
width: double.infinity,
decoration: BoxDecoration(
color: CribsTheme.of(context).secondaryBackground,
borderRadius: BorderRadius.circular(20),
shape: BoxShape.rectangle,
),
child: SingleChildScrollView(
child: Container(
height:
(MediaQuery.of(context).orientation == Orientation.portrait)
? 660
: SizeConfig.screenHeight! * 0.85,
child: Padding(
padding: EdgeInsets.fromLTRB(10, 0, 10, 20),
child: PaywallView(
onPurchaseError: (PurchasesError) {
showSnackbar(context, PurchasesError.message);
},
onPurchaseCompleted:
(customerInfo, storeTransaction) async {
// some code to update customer info
},
offering: (tier == 'PRO') ? proOffering : ultraOffering,
)))));
}
The code works well for IOS. There are no issues with the rendering and everything works fine. All Paywalls are displayed nicely (although we can’t change the font sizes, etc).
But in Android, the Paywall doesn’t render correctly. The ULTRA offering is somehow defaulted and no matter what we do, including PaywallFooterView, the same result occurs. If we remove one Paywall (either PRO or ULTRA), it’s works correctly.
We have changed the mainActivity.kt, otherwise it will crash in Android:
package com.nborder.cribs.android
import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity: FlutterFragmentActivity()
But this behavior is unexpected. It seems that in Android, we can only display 1 Paywall at a time, but in IOS we are able display both Paywalls.
On debugging, we confirm that we are passing the correct offering to PaywallView each time. This ONLY happens in Android.
As a result, as a workaround, we had to revert back to the OLD way of doing this. We wrote some code just for Android that is not using the Paywall and calls the Purchase API directly, and left iOS the way it is. That is - if Platform.Android - show custom code without Paywall, if Platform.IOS - show paywalls.
We’ve tried the latest version of purchases_flutter and purchases_flutter_ui - versions 8.1.0 all the way down to 7.0.2. Both PaywallView and PaywallFooterView have the same issue.
I’m not going to show Flutter Doctor -v - it’s not helpful at all. But rest assured, it all works.
I’m wondering if anyone in the community has encountered this issue?
Kind regards,
Alan