Skip to content

Commit e54252c

Browse files
authored
feat(firebase_analytics): add logInAppPurchase support for iOS (#17851)
* feat(firebase_analytics): add `logInAppPurchase` support for iOS and Android * feat(firebase_analytics): restrict `logInAppPurchase` to iOS * chore: update `logInAppPurchase` to use `defaultTargetPlatform` for iOS check * test: add test for `logInAppPurchase`
1 parent 0f9c445 commit e54252c

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

packages/firebase_analytics/firebase_analytics/lib/src/firebase_analytics.dart

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,6 +1205,43 @@ class FirebaseAnalytics extends FirebasePluginPlatform {
12051205
);
12061206
}
12071207

1208+
/// Logs the standard `in_app_purchase` event.
1209+
///
1210+
/// This event signifies that an item(s) was purchased by a user.
1211+
///
1212+
/// This API supports manually logging in-app purchase events on iOS and Android.
1213+
/// This is especially useful in cases where purchases happen outside the native
1214+
/// billing systems (e.g. custom payment flows).
1215+
Future<void> logInAppPurchase({
1216+
String? currency,
1217+
bool? freeTrial,
1218+
double? price,
1219+
bool? priceIsDiscounted,
1220+
String? productID,
1221+
String? productName,
1222+
int? quantity,
1223+
bool? subscription,
1224+
num? value,
1225+
}) {
1226+
if (defaultTargetPlatform != TargetPlatform.iOS) {
1227+
throw UnimplementedError('logInAppPurchase() is only supported on iOS.');
1228+
}
1229+
return _delegate.logEvent(
1230+
name: 'in_app_purchase',
1231+
parameters: filterOutNulls(<String, Object?>{
1232+
_CURRENCY: currency,
1233+
_FREE_TRIAL: freeTrial,
1234+
_PRICE: price,
1235+
_PRICE_IS_DISCOUNTED: priceIsDiscounted,
1236+
_PRODUCT_ID: productID,
1237+
_PRODUCT_NAME: productName,
1238+
_QUANTITY: quantity,
1239+
_SUBSCRIPTION: subscription,
1240+
_VALUE: value,
1241+
}),
1242+
);
1243+
}
1244+
12081245
/// Sets the duration of inactivity that terminates the current session.
12091246
///
12101247
/// The default value is 1800000 milliseconds (30 minutes).
@@ -1547,3 +1584,24 @@ const String _PROMOTION_ID = 'promotion_id';
15471584

15481585
/// The name of a product promotion
15491586
const String _PROMOTION_NAME = 'promotion_name';
1587+
1588+
/// Whether the purchase is a free trial
1589+
const String _FREE_TRIAL = 'free_trial';
1590+
1591+
/// The price of the item
1592+
const String _PRICE = 'price';
1593+
1594+
/// Whether the price is discounted
1595+
const String _PRICE_IS_DISCOUNTED = 'price_is_discounted';
1596+
1597+
/// The ID of the product
1598+
const String _PRODUCT_ID = 'product_id';
1599+
1600+
/// The name of the product
1601+
const String _PRODUCT_NAME = 'product_name';
1602+
1603+
/// The quantity of the product
1604+
const String _QUANTITY = 'quantity';
1605+
1606+
/// Whether the purchase is a subscription
1607+
const String _SUBSCRIPTION = 'subscription';

tests/integration_test/firebase_analytics/firebase_analytics_e2e_test.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,27 @@ void main() {
170170
);
171171
});
172172

173+
test(
174+
'logInAppPurchase',
175+
() async {
176+
await expectLater(
177+
FirebaseAnalytics.instance.logInAppPurchase(
178+
currency: 'USD',
179+
freeTrial: false,
180+
price: 4.99,
181+
priceIsDiscounted: false,
182+
productID: 'com.example.product',
183+
productName: 'Example Product',
184+
quantity: 1,
185+
subscription: true,
186+
value: 4.99,
187+
),
188+
completes,
189+
);
190+
},
191+
skip: defaultTargetPlatform != TargetPlatform.iOS,
192+
);
193+
173194
test('setUserId', () async {
174195
await expectLater(
175196
FirebaseAnalytics.instance.setUserId(id: 'foo'),

0 commit comments

Comments
 (0)