Skip to content

Commit

Permalink
feat(analytics, ios): implement on-device conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
mikehardy committed Jun 22, 2022
1 parent 5da99bd commit a1df996
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"jest": "^28.1.1",
"lerna": "5.1.4",
"prettier": "^2.7.1",
"regenerator-transform": "^0.15.0",
"rimraf": "^3.0.2",
"shelljs": "^0.8.5",
"ts-jest": "^28.0.5",
Expand Down
12 changes: 12 additions & 0 deletions packages/analytics/RNFBAnalytics.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ Pod::Spec.new do |s|
s.dependency 'Firebase/Analytics', firebase_sdk_version
end

# Special pod for on-device conversion
if defined?($RNFirebaseAnalyticsGoogleAppMeasurementOnDeviceConversion) && ($RNFirebaseAnalyticsGoogleAppMeasurementOnDeviceConversion == true)
Pod::UI.puts "#{s.name}: GoogleAppMeasurementOnDeviceConversion pod added"

# Releasing as non-breaking change as it is optional but it raises minimum requirements, validate just in case
if (Gem::Version.new(firebase_sdk_version) < Gem::Version.new("9.0.0"))
raise "GoogleAppMeasurementOnDeviceConversion requires firebase-ios-sdk 9.0.0 or greater."
end

s.dependency 'GoogleAppMeasurementOnDeviceConversion', firebase_sdk_version
end

if defined?($RNFirebaseAsStaticFramework)
Pod::UI.puts "#{s.name}: Using overridden static_framework value of '#{$RNFirebaseAsStaticFramework}'"
s.static_framework = $RNFirebaseAsStaticFramework
Expand Down
11 changes: 11 additions & 0 deletions packages/analytics/__tests__/analytics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -521,4 +521,15 @@ describe('Analytics', function () {
);
});
});

describe('initiateOnDeviceConversionMeasurementWithEmailAddress()', function () {
it('throws if not a string', function () {
expect(() =>
// @ts-ignore
firebase.analytics().initiateOnDeviceConversionMeasurementWithEmailAddress(true),
).toThrowError(
"firebase.analytics().initiateOnDeviceConversionMeasurementWithEmailAddress(*) 'emailAddress' expected a string value.",
);
});
});
});
9 changes: 9 additions & 0 deletions packages/analytics/e2e/analytics.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,15 @@ describe('analytics()', function () {
});
});

// Test this last so it does not stop delivery to DebugView
describe('initiateOnDeviceConversionMeasurementWithEmailAddress()', function () {
it('calls native API successfully', async function () {
await firebase
.analytics()
.initiateOnDeviceConversionMeasurementWithEmailAddress('conversionTest@example.com');
});
});

// Test this last so it does not stop delivery to DebugView
describe('setAnalyticsCollectionEnabled()', function () {
it('false', async function () {
Expand Down
13 changes: 13 additions & 0 deletions packages/analytics/ios/RNFBAnalytics/RNFBAnalyticsModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,19 @@ - (dispatch_queue_t)methodQueue {
return resolve([NSNull null]);
}

RCT_EXPORT_METHOD(initiateOnDeviceConversionMeasurementWithEmailAddress
: (NSString *)emailAddress resolver
: (RCTPromiseResolveBlock)resolve rejecter
: (RCTPromiseRejectBlock)reject) {
@try {
[FIRAnalytics initiateOnDeviceConversionMeasurementWithEmailAddress:emailAddress];
} @catch (NSException *exception) {
return [RNFBSharedUtils rejectPromiseWithExceptionDict:reject exception:exception];
}

return resolve([NSNull null]);
}

#pragma mark -
#pragma mark Private methods

Expand Down
9 changes: 9 additions & 0 deletions packages/analytics/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1502,6 +1502,15 @@ export namespace FirebaseAnalyticsTypes {
* will clear all parameters.
*/
setDefaultEventParameters(params?: { [key: string]: any }): Promise<void>;

/**
* start privacy-sensitive on-device conversion management.
* This is iOS-only.
* This is a no-op if you do not include '#RNFirebaseAnalyticsGoogleAppMeasurementOnDeviceConversion = true' in your Podfile
*
* @param emailAddress email address, properly formatted complete with domain name e.g, 'user@example.com'
*/
initiateOnDeviceConversionMeasurementWithEmailAddress(emailAddress: string): Promise<void>;
}
}

Expand Down
15 changes: 15 additions & 0 deletions packages/analytics/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import {
isAlphaNumericUnderscore,
isIOS,
isNull,
isNumber,
isObject,
Expand Down Expand Up @@ -676,6 +677,20 @@ class FirebaseAnalyticsModule extends FirebaseModule {

return this.native.setDefaultEventParameters(params);
}

initiateOnDeviceConversionMeasurementWithEmailAddress(emailAddress) {
if (!isString(emailAddress)) {
throw new Error(
"firebase.analytics().initiateOnDeviceConversionMeasurementWithEmailAddress(*) 'emailAddress' expected a string value.",
);
}

if (!isIOS) {
return;
}

return this.native.initiateOnDeviceConversionMeasurementWithEmailAddress(emailAddress);
}
}

// import { SDK_VERSION } from '@react-native-firebase/analytics';
Expand Down
3 changes: 3 additions & 0 deletions tests/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ $RNFirebaseAsStaticFramework = true # toggle this to true (and set 'use_framewor
# See: https://firebase.google.com/support/release-notes/ios#analytics - requires firebase-ios-sdk 7.11.0+
#$RNFirebaseAnalyticsWithoutAdIdSupport = true # toggle this to true for the no-ad-tracking Analytics subspec

# Toggle this to true if you want to include support for on device conversion measurement APIs
$RNFirebaseAnalyticsGoogleAppMeasurementOnDeviceConversion = true

# Versions used below, for quick reference / outdated+upgrade checks
$iOSMinimumDeployVersion = '11.0'

Expand Down

1 comment on commit a1df996

@vercel
Copy link

@vercel vercel bot commented on a1df996 Jun 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.