diff --git a/packages/analytics/android/src/reactnative/java/io/invertase/firebase/analytics/ReactNativeFirebaseAnalyticsModule.java b/packages/analytics/android/src/reactnative/java/io/invertase/firebase/analytics/ReactNativeFirebaseAnalyticsModule.java index cf909b282f..638d98991a 100644 --- a/packages/analytics/android/src/reactnative/java/io/invertase/firebase/analytics/ReactNativeFirebaseAnalyticsModule.java +++ b/packages/analytics/android/src/reactnative/java/io/invertase/firebase/analytics/ReactNativeFirebaseAnalyticsModule.java @@ -18,11 +18,16 @@ */ +import android.os.Bundle; + import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReadableMap; +import com.google.firebase.analytics.FirebaseAnalytics; + +import java.util.ArrayList; import javax.annotation.Nullable; @@ -39,7 +44,7 @@ public class ReactNativeFirebaseAnalyticsModule extends ReactNativeFirebaseModul @ReactMethod public void logEvent(String name, @Nullable ReadableMap params, Promise promise) { - module.logEvent(name, Arguments.toBundle(params)).addOnCompleteListener(task -> { + module.logEvent(name, toBundle(params)).addOnCompleteListener(task -> { if (task.isSuccessful()) { promise.resolve(task.getResult()); } else { @@ -114,4 +119,19 @@ public void resetAnalyticsData(Promise promise) { } }); } + + private Bundle toBundle(ReadableMap readableMap) { + Bundle bundle = Arguments.toBundle(readableMap); + if (bundle == null) { + return null; + } + ArrayList itemsArray = (ArrayList) bundle.getSerializable(FirebaseAnalytics.Param.ITEMS); + for (Object item : itemsArray != null ? itemsArray : new ArrayList()) { + if (item instanceof Bundle && ((Bundle) item).containsKey(FirebaseAnalytics.Param.QUANTITY)) { + double number = ((Bundle) item).getDouble(FirebaseAnalytics.Param.QUANTITY); + ((Bundle) item).putInt(FirebaseAnalytics.Param.QUANTITY, (int) number); + } + } + return bundle; + } } diff --git a/packages/analytics/e2e/analytics.e2e.js b/packages/analytics/e2e/analytics.e2e.js index 6b3e25bb6c..e2b65ea467 100644 --- a/packages/analytics/e2e/analytics.e2e.js +++ b/packages/analytics/e2e/analytics.e2e.js @@ -141,6 +141,7 @@ describe('analytics()', () => { item_name: 'foo', item_category: 'foo', item_location_id: 'foo', + quantity: 5, }, ], value: 123, diff --git a/packages/analytics/ios/RNFBAnalytics/RNFBAnalyticsModule.m b/packages/analytics/ios/RNFBAnalytics/RNFBAnalyticsModule.m index 1507a532d9..74d12dad13 100644 --- a/packages/analytics/ios/RNFBAnalytics/RNFBAnalyticsModule.m +++ b/packages/analytics/ios/RNFBAnalytics/RNFBAnalyticsModule.m @@ -44,7 +44,7 @@ - (dispatch_queue_t)methodQueue { rejecter: (RCTPromiseRejectBlock) reject) { @try { - [FIRAnalytics logEventWithName:name parameters:params]; + [FIRAnalytics logEventWithName:name parameters:[self cleanJavascriptParams:params]]; } @catch (NSException *exception) { return [RNFBSharedUtils rejectPromiseWithExceptionDict:reject exception:exception]; } @@ -135,4 +135,23 @@ - (dispatch_queue_t)methodQueue { return resolve([NSNull null]); } +#pragma mark - +#pragma mark Private methods + + - (NSDictionary *)cleanJavascriptParams:(NSDictionary *)params { + NSMutableDictionary *newParams = [params mutableCopy]; + if (newParams[kFIRParameterItems]) { + NSMutableArray *newItems = [NSMutableArray array]; + [(NSArray *)newParams[kFIRParameterItems] enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + NSMutableDictionary *item = [obj mutableCopy]; + if (item[kFIRParameterQuantity]) { + item[kFIRParameterQuantity] = @([item[kFIRParameterQuantity] integerValue]); + } + [newItems addObject:[item copy]]; + }]; + newParams[kFIRParameterItems] = [newItems copy]; + } + return [newParams copy]; + } + @end diff --git a/packages/analytics/lib/index.d.ts b/packages/analytics/lib/index.d.ts index 06bf32ebb9..dcb9289e7c 100644 --- a/packages/analytics/lib/index.d.ts +++ b/packages/analytics/lib/index.d.ts @@ -99,7 +99,12 @@ export namespace FirebaseAnalyticsTypes { * The Item variant. */ item_variant?: string; + /** + * The Item quantity. + */ + quantity?: number; } + export interface AddPaymentInfoEventParameters { items?: Item[]; /** diff --git a/packages/analytics/lib/structs.js b/packages/analytics/lib/structs.js index 87f7d54603..a1037b8f3d 100644 --- a/packages/analytics/lib/structs.js +++ b/packages/analytics/lib/structs.js @@ -28,6 +28,7 @@ const Item = struct({ item_list_name: 'string?', item_location_id: 'string?', item_variant: 'string?', + quantity: 'number?', }); export const ScreenView = struct({