Question

Subscription not detected on iOS / Flutter (Is revenue cat working for flutter ios or not ?)

  • 17 May 2024
  • 1 reply
  • 26 views

Badge +2
Future<void> checkAndUpdateSubscriptionStatus() async {
try {
print("Fetching customer info...");
CustomerInfo customerInfo = await Purchases.getCustomerInfo();
print("Customer info fetched successfully.");
print("Active entitlements: ${customerInfo.entitlements.active}");

if (customerInfo.entitlements.active.isNotEmpty) {
// User has at least one active entitlement
print("User has at least one active entitlement.");

if (customerInfo.entitlements.all["50inquiries"]?.isActive ?? false) {
// User has an active "50inquiries" subscription
print("User has an active '50inquiries' subscription.");
AppData.isVip = 1;
} else if (customerInfo.entitlements.all["unlimited"]?.isActive ??
false) {
// User has an active "unlimited" subscription
print("User has an active 'unlimited' subscription.");
AppData.isVip = 2;
} else {
print(
"User does not have an active '50inquiries' or 'unlimited' subscription.");
}
} else {
// User has no active subscriptions
print("User has no active subscriptions.");
AppData.isVip = 0;
}
} catch (e) {
print("Error fetching subscription status: $e");
}
}


void _showSettingsMenu(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setModalState) {
// Check if the device is in landscape mode
bool isLandscape =
MediaQuery.of(context).orientation == Orientation.landscape;

return Container(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30), // Adjust the radius as needed
topRight:
Radius.circular(30), // Adjust the radius as needed
),
),
child: SingleChildScrollView(
// Allows the content to be scrollable
padding: EdgeInsets.only(
top: 5), // Add padding to align with the top border
child: Container(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
child: Wrap(
// Adjusts layout based on screen width
alignment: WrapAlignment.center,
runSpacing: 10, // Space between rows
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.light_mode, color: Colors.green),
Switch(
value: isDarkTheme,
onChanged: (value) {
setModalState(() {
isDarkTheme =
value; // Update the local state within the modal
});
setState(() {
isDarkTheme =
value; // Also update the app-wide state
});
Navigator.pop(
context); // Optionally close the sheet after changing the theme
},
),
Icon(Icons.dark_mode, color: Colors.green),
],
),
ListTile(
leading: Icon(Icons.help, color: Colors.green),
title: Text('Help',
style: TextStyle(color: Colors.green)),
onTap: () {
// Handle help tap
Navigator.pop(context); // Close the bottom sheet
},
),
Text('Choose your plan:',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.green)),
SizedBox(
height:
10), // Provides space between text and cards
SubscriptionOption(
title: 'Free',
description: 'Up to 5 daily inquiries.',
function: () {
//Add your free logic here
}),
SubscriptionOption(
title: 'Pro',
description: 'Up to 50 daily inquiries.',
function: () async {
dev.log("Clicked pro");
Get.back();
//We will show the monthly pro paywall
Offerings offerings =
await Purchases.getOfferings();
final paywallResult =
await RevenueCatUI.presentPaywall(
offering: offerings.all.entries
.firstWhere((element) =>
element.value.identifier ==
"50InquiriesOffering")
.value,
displayCloseButton: true);
dev.log(
'Paywall result: $paywallResult'); //You can use this result for anything you want
try {
CustomerInfo customerInfo =
await Purchases.getCustomerInfo();
if (customerInfo
.entitlements.active.isNotEmpty) {
if (customerInfo
.entitlements.active.isNotEmpty) {
AppData.isVip = customerInfo
.entitlements.active.entries
.where((element) =>
element.value.identifier == "")
.isNotEmpty
? 2
: //We check if there is an active monthly unlimited subscription, we set it to 2
customerInfo.entitlements.active.entries
.where((element) =>
element.value.identifier ==
"")
.isNotEmpty
? 1
: //We check if there is an active monthly pro subscription, we set it to 1
0; //If there is no active subscription, we set it to 0
//As subcription changed, update your UI accodingly
setState(() {});
}
dev.log("active plan=${AppData.isVip}");
}
} on PlatformException catch (e) {
// Error fetching purchaser info
}
}),
SubscriptionOption(
title: 'Expert',
description: 'Unlimited inquiries.',
function: () async {
dev.log("Clicked unlimited");
Get.back();
Offerings offerings =
await Purchases.getOfferings();
//We will show the monthly unlimited paywall
final paywallResult =
await RevenueCatUI.presentPaywall(
offering: offerings.all.entries
.firstWhere((element) =>
element.value.identifier ==
"UnlimitedInquiriesOffering")
.value,
displayCloseButton: true);
dev.log(
'Paywall result: $paywallResult'); //You can use this result for anything you want
try {
CustomerInfo customerInfo =
await Purchases.getCustomerInfo();
if (customerInfo
.entitlements.active.isNotEmpty) {
if (customerInfo
.entitlements.active.isNotEmpty) {
AppData.isVip = customerInfo
.entitlements.active.entries
.where((element) =>
element.value.identifier == "")
.isNotEmpty
? 2
: //We check if there is an active monthly unlimited subscription, we set it to 2
customerInfo.entitlements.active.entries
.where((element) =>
element.value.identifier ==
"")
.isNotEmpty
? 1
: //We check if there is an active monthly pro subscription, we set it to 1
0; //If there is no active subscription, we set it to 0
//As subcription changed, update your UI accodingly
setState(() {});
}
dev.log("active plan=${AppData.isVip}");
}
} on PlatformException catch (e) {
// Error fetching purchaser info
}
}),
ListTile(
leading: Icon(Icons.logout, color: Colors.green),
title: Text('Logout',
style: TextStyle(color: Colors.green)),
onTap: () async {
// Handle logout tap
await FirebaseAuth.instance
.signOut(); // Sign out from Firebase
Navigator.pop(context); // Close the bottom sheet

// Navigate back to the LandingPage
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => LandingPage()));
},
),
ListTile(
leading:
Icon(Icons.delete_forever, color: Colors.red),
title: Text('Delete Account',
style: TextStyle(color: Colors.red)),
onTap: () async {
// Close the bottom sheet
Navigator.pop(context);
// Show confirmation dialog
_showDeleteAccountConfirmation(context);
},
),
],
),
),
));
},
);
},
);
}

The app is in prod. I can see the subscription in the console but the sdk doesn't capture it from the user device. Its very bad because I have see other users complaining about the same issue with the sdk on flutter an iOS. What is going on?


This post has been closed for comments

1 reply

Userlevel 4
Badge +8

Hi,

Could you open a support request with an example app_user_id so we can take a closer look?

Thanks!