Skip to main content
Question

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

  • May 17, 2024
  • 1 reply
  • 81 views

Forum|alt.badge.img+3
1Future<void> checkAndUpdateSubscriptionStatus() async {
2 try {
3 print("Fetching customer info...");
4 CustomerInfo customerInfo = await Purchases.getCustomerInfo();
5 print("Customer info fetched successfully.");
6 print("Active entitlements: ${customerInfo.entitlements.active}");
7
8 if (customerInfo.entitlements.active.isNotEmpty) {
9 // User has at least one active entitlement
10 print("User has at least one active entitlement.");
11
12 if (customerInfo.entitlements.all["50inquiries"]?.isActive ?? false) {
13 // User has an active "50inquiries" subscription
14 print("User has an active '50inquiries' subscription.");
15 AppData.isVip = 1;
16 } else if (customerInfo.entitlements.all["unlimited"]?.isActive ??
17 false) {
18 // User has an active "unlimited" subscription
19 print("User has an active 'unlimited' subscription.");
20 AppData.isVip = 2;
21 } else {
22 print(
23 "User does not have an active '50inquiries' or 'unlimited' subscription.");
24 }
25 } else {
26 // User has no active subscriptions
27 print("User has no active subscriptions.");
28 AppData.isVip = 0;
29 }
30 } catch (e) {
31 print("Error fetching subscription status: $e");
32 }
33 }
34
35
36void _showSettingsMenu(BuildContext context) {
37 showModalBottomSheet(
38 context: context,
39 builder: (BuildContext context) {
40 return StatefulBuilder(
41 builder: (BuildContext context, StateSetter setModalState) {
42 // Check if the device is in landscape mode
43 bool isLandscape =
44 MediaQuery.of(context).orientation == Orientation.landscape;
45
46 return Container(
47 padding: EdgeInsets.symmetric(vertical: 20, horizontal: 10),
48 decoration: BoxDecoration(
49 borderRadius: BorderRadius.only(
50 topLeft: Radius.circular(30), // Adjust the radius as needed
51 topRight:
52 Radius.circular(30), // Adjust the radius as needed
53 ),
54 ),
55 child: SingleChildScrollView(
56 // Allows the content to be scrollable
57 padding: EdgeInsets.only(
58 top: 5), // Add padding to align with the top border
59 child: Container(
60 padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
61 child: Wrap(
62 // Adjusts layout based on screen width
63 alignment: WrapAlignment.center,
64 runSpacing: 10, // Space between rows
65 children: <Widget>[
66 Row(
67 mainAxisAlignment: MainAxisAlignment.spaceBetween,
68 children: [
69 Icon(Icons.light_mode, color: Colors.green),
70 Switch(
71 value: isDarkTheme,
72 onChanged: (value) {
73 setModalState(() {
74 isDarkTheme =
75 value; // Update the local state within the modal
76 });
77 setState(() {
78 isDarkTheme =
79 value; // Also update the app-wide state
80 });
81 Navigator.pop(
82 context); // Optionally close the sheet after changing the theme
83 },
84 ),
85 Icon(Icons.dark_mode, color: Colors.green),
86 ],
87 ),
88 ListTile(
89 leading: Icon(Icons.help, color: Colors.green),
90 title: Text('Help',
91 style: TextStyle(color: Colors.green)),
92 onTap: () {
93 // Handle help tap
94 Navigator.pop(context); // Close the bottom sheet
95 },
96 ),
97 Text('Choose your plan:',
98 style: TextStyle(
99 fontSize: 16,
100 fontWeight: FontWeight.bold,
101 color: Colors.green)),
102 SizedBox(
103 height:
104 10), // Provides space between text and cards
105 SubscriptionOption(
106 title: 'Free',
107 description: 'Up to 5 daily inquiries.',
108 function: () {
109 //Add your free logic here
110 }),
111 SubscriptionOption(
112 title: 'Pro',
113 description: 'Up to 50 daily inquiries.',
114 function: () async {
115 dev.log("Clicked pro");
116 Get.back();
117 //We will show the monthly pro paywall
118 Offerings offerings =
119 await Purchases.getOfferings();
120 final paywallResult =
121 await RevenueCatUI.presentPaywall(
122 offering: offerings.all.entries
123 .firstWhere((element) =>
124 element.value.identifier ==
125 "50InquiriesOffering")
126 .value,
127 displayCloseButton: true);
128 dev.log(
129 'Paywall result: $paywallResult'); //You can use this result for anything you want
130 try {
131 CustomerInfo customerInfo =
132 await Purchases.getCustomerInfo();
133 if (customerInfo
134 .entitlements.active.isNotEmpty) {
135 if (customerInfo
136 .entitlements.active.isNotEmpty) {
137 AppData.isVip = customerInfo
138 .entitlements.active.entries
139 .where((element) =>
140 element.value.identifier == "")
141 .isNotEmpty
142 ? 2
143 : //We check if there is an active monthly unlimited subscription, we set it to 2
144 customerInfo.entitlements.active.entries
145 .where((element) =>
146 element.value.identifier ==
147 "")
148 .isNotEmpty
149 ? 1
150 : //We check if there is an active monthly pro subscription, we set it to 1
151 0; //If there is no active subscription, we set it to 0
152 //As subcription changed, update your UI accodingly
153 setState(() {});
154 }
155 dev.log("active plan=${AppData.isVip}");
156 }
157 } on PlatformException catch (e) {
158 // Error fetching purchaser info
159 }
160 }),
161 SubscriptionOption(
162 title: 'Expert',
163 description: 'Unlimited inquiries.',
164 function: () async {
165 dev.log("Clicked unlimited");
166 Get.back();
167 Offerings offerings =
168 await Purchases.getOfferings();
169 //We will show the monthly unlimited paywall
170 final paywallResult =
171 await RevenueCatUI.presentPaywall(
172 offering: offerings.all.entries
173 .firstWhere((element) =>
174 element.value.identifier ==
175 "UnlimitedInquiriesOffering")
176 .value,
177 displayCloseButton: true);
178 dev.log(
179 'Paywall result: $paywallResult'); //You can use this result for anything you want
180 try {
181 CustomerInfo customerInfo =
182 await Purchases.getCustomerInfo();
183 if (customerInfo
184 .entitlements.active.isNotEmpty) {
185 if (customerInfo
186 .entitlements.active.isNotEmpty) {
187 AppData.isVip = customerInfo
188 .entitlements.active.entries
189 .where((element) =>
190 element.value.identifier == "")
191 .isNotEmpty
192 ? 2
193 : //We check if there is an active monthly unlimited subscription, we set it to 2
194 customerInfo.entitlements.active.entries
195 .where((element) =>
196 element.value.identifier ==
197 "")
198 .isNotEmpty
199 ? 1
200 : //We check if there is an active monthly pro subscription, we set it to 1
201 0; //If there is no active subscription, we set it to 0
202 //As subcription changed, update your UI accodingly
203 setState(() {});
204 }
205 dev.log("active plan=${AppData.isVip}");
206 }
207 } on PlatformException catch (e) {
208 // Error fetching purchaser info
209 }
210 }),
211 ListTile(
212 leading: Icon(Icons.logout, color: Colors.green),
213 title: Text('Logout',
214 style: TextStyle(color: Colors.green)),
215 onTap: () async {
216 // Handle logout tap
217 await FirebaseAuth.instance
218 .signOut(); // Sign out from Firebase
219 Navigator.pop(context); // Close the bottom sheet
220
221 // Navigate back to the LandingPage
222 Navigator.pushReplacement(
223 context,
224 MaterialPageRoute(
225 builder: (context) => LandingPage()));
226 },
227 ),
228 ListTile(
229 leading:
230 Icon(Icons.delete_forever, color: Colors.red),
231 title: Text('Delete Account',
232 style: TextStyle(color: Colors.red)),
233 onTap: () async {
234 // Close the bottom sheet
235 Navigator.pop(context);
236 // Show confirmation dialog
237 _showDeleteAccountConfirmation(context);
238 },
239 ),
240 ],
241 ),
242 ),
243 ));
244 },
245 );
246 },
247 );
248 }

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

Ryan Glanz
RevenueCat Staff
Forum|alt.badge.img+8
  • RevenueCat Staff
  • 384 replies
  • May 21, 2024

Hi,

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

Thanks!


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings