Skip to content

Commit 4f6daf7

Browse files
authored
Add support for on-device conversions using hashed email address and phone number. (#1603)
* Add function header for hashed email address and phone number functions. * Format code. * Add integration test for hashed email/phone. Add stub. Fix header definition. * Add missing header. * Format code. * Fix Doxygen. * Add iOS implementation. * Add iOS implementation. * Format code. * Add readme. * Fix usage. * Capitalize SHA
1 parent c517451 commit 4f6daf7

File tree

8 files changed

+107
-0
lines changed

8 files changed

+107
-0
lines changed

analytics/integration_test/src/integration_test.cc

+20
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,26 @@ TEST_F(FirebaseAnalyticsTest, TestSetProperties) {
220220
221221
firebase::analytics::InitiateOnDeviceConversionMeasurementWithPhoneNumber(
222222
"+15551234567");
223+
224+
std::vector<unsigned char> hashed_email = {
225+
// SHA256-encoded "[email protected]"
226+
0x31, 0xc5, 0x54, 0x3c, 0x17, 0x34, 0xd2, 0x5c, 0x72, 0x06, 0xf5,
227+
0xfd, 0x59, 0x15, 0x25, 0xd0, 0x29, 0x5b, 0xec, 0x6f, 0xe8, 0x4f,
228+
0xf8, 0x2f, 0x94, 0x6a, 0x34, 0xfe, 0x97, 0x0a, 0x1e, 0x66,
229+
};
230+
231+
firebase::analytics::
232+
InitiateOnDeviceConversionMeasurementWithHashedEmailAddress(hashed_email);
233+
234+
std::vector<unsigned char> hashed_phone = {
235+
// SHA256-encoded "+12345556789"
236+
0x12, 0x8c, 0x64, 0xfe, 0x24, 0x0f, 0x08, 0x75, 0xf5, 0x98, 0xc3,
237+
0x48, 0x0e, 0xb0, 0x38, 0xd2, 0xe6, 0xb0, 0x05, 0xd1, 0xa0, 0x57,
238+
0xb6, 0x21, 0x4a, 0xc2, 0x09, 0xf6, 0xe5, 0xc0, 0x68, 0x41,
239+
};
240+
241+
firebase::analytics::
242+
InitiateOnDeviceConversionMeasurementWithHashedPhoneNumber(hashed_phone);
223243
}
224244

225245
TEST_F(FirebaseAnalyticsTest, TestLogEvents) {

analytics/src/analytics_android.cc

+20
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,26 @@ void InitiateOnDeviceConversionMeasurementWithPhoneNumber(
451451
// No-op on Android
452452
}
453453

454+
/// Initiates on-device conversion measurement given a hashed user email address
455+
/// on iOS (no-op on Android). On iOS, requires dependency
456+
/// GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a
457+
/// no-op.
458+
void InitiateOnDeviceConversionMeasurementWithHashedEmailAddress(
459+
std::vector<unsigned char> hashed_email) {
460+
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
461+
// No-op on Android
462+
}
463+
464+
/// Initiates on-device conversion measurement given a hashed phone number on
465+
/// iOS (no-op on Android). On iOS, requires dependency
466+
/// GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a
467+
/// no-op.
468+
void InitiateOnDeviceConversionMeasurementWithHashedPhoneNumber(
469+
std::vector<unsigned char> hashed_phone) {
470+
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
471+
// No-op on Android
472+
}
473+
454474
// Set a user property to the given value.
455475
void SetUserProperty(const char* name, const char* value) {
456476
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());

analytics/src/analytics_ios.mm

+24
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,30 @@ void InitiateOnDeviceConversionMeasurementWithPhoneNumber(const char* phone_numb
280280
[FIRAnalytics initiateOnDeviceConversionMeasurementWithPhoneNumber:@(phone_number)];
281281
}
282282

283+
/// Initiates on-device conversion measurement given a hashed user email address
284+
/// on iOS (no-op on Android). On iOS, requires dependency
285+
/// GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a
286+
/// no-op.
287+
void InitiateOnDeviceConversionMeasurementWithHashedEmailAddress(
288+
std::vector<unsigned char> hashed_email) {
289+
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
290+
NSData* hashed_email_data =
291+
firebase::util::BytesToNSData(hashed_email.data(), hashed_email.size());
292+
[FIRAnalytics initiateOnDeviceConversionMeasurementWithHashedEmailAddress:hashed_email_data];
293+
}
294+
295+
/// Initiates on-device conversion measurement given a hashed phone number on
296+
/// iOS (no-op on Android). On iOS, requires dependency
297+
/// GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a
298+
/// no-op.
299+
void InitiateOnDeviceConversionMeasurementWithHashedPhoneNumber(
300+
std::vector<unsigned char> hashed_phone) {
301+
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
302+
NSData* hashed_phone_data =
303+
firebase::util::BytesToNSData(hashed_phone.data(), hashed_phone.size());
304+
[FIRAnalytics initiateOnDeviceConversionMeasurementWithHashedPhoneNumber:hashed_phone_data];
305+
}
306+
283307
// Set a user property to the given value.
284308
void SetUserProperty(const char* name, const char* value) {
285309
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());

analytics/src/analytics_stub.cc

+10
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ void InitiateOnDeviceConversionMeasurementWithEmailAddress(
106106
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
107107
}
108108

109+
void InitiateOnDeviceConversionMeasurementWithHashedEmailAddress(
110+
std::vector<unsigned char> email_address) {
111+
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
112+
}
113+
109114
/// Initiates on-device conversion measurement given a phone number on iOS
110115
/// (no-op on Android). On iOS, requires dependency
111116
/// GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a
@@ -115,6 +120,11 @@ void InitiateOnDeviceConversionMeasurementWithPhoneNumber(
115120
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
116121
}
117122

123+
void InitiateOnDeviceConversionMeasurementWithHashedPhoneNumber(
124+
std::vector<unsigned char> phone_number_hash) {
125+
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
126+
}
127+
118128
// Set a user property to the given value.
119129
void SetUserProperty(const char* /*name*/, const char* /*value*/) {
120130
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());

analytics/src/include/firebase/analytics.h

+20
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <cstdint>
2222
#include <map>
2323
#include <string>
24+
#include <vector>
2425

2526
#include "firebase/app.h"
2627
#include "firebase/future.h"
@@ -503,6 +504,25 @@ void InitiateOnDeviceConversionMeasurementWithEmailAddress(
503504
void InitiateOnDeviceConversionMeasurementWithPhoneNumber(
504505
const char* phone_number);
505506

507+
/// Initiates on-device conversion measurement given a SHA256-hashed user email
508+
/// address. Requires dependency GoogleAppMeasurementOnDeviceConversion to be
509+
/// linked in, otherwise it is a no-op.
510+
/// @param hashed_email_address User email address as a UTF8-encoded string
511+
/// normalized and hashed according to the instructions at
512+
/// https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3.
513+
void InitiateOnDeviceConversionMeasurementWithHashedEmailAddress(
514+
std::vector<unsigned char> hashed_email_address);
515+
516+
/// Initiates on-device conversion measurement given a SHA256-hashed phone
517+
/// number in E.164 format. Requires dependency
518+
/// GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a
519+
/// no-op.
520+
/// @param hashed_phone_number UTF8-encoded user phone number in E.164 format
521+
/// and then hashed according to the instructions at
522+
/// https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3.
523+
void InitiateOnDeviceConversionMeasurementWithHashedPhoneNumber(
524+
std::vector<unsigned char> hashed_phone_number);
525+
506526
/// @brief Set a user property to the given value.
507527
///
508528
/// Properties associated with a user allow a developer to segment users

app/src/util_ios.h

+3
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ NSData *StringToNSData(const std::string &str);
217217
// Convert bytes to NSData.
218218
NSData *BytesToNSData(const char *bytes, const int len);
219219

220+
// Convert bytes to NSData.
221+
NSData *BytesToNSData(const unsigned char *bytes, const int len);
222+
220223
// Convert an NSData to std::string.
221224
std::string NSDataToString(NSData *data);
222225

app/src/util_ios.mm

+4
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ void ForEachAppDelegateClass(void (^block)(Class)) {
139139
return [NSData dataWithBytes:bytes length:len];
140140
}
141141

142+
NSData *BytesToNSData(const unsigned char *bytes, const int len) {
143+
return [NSData dataWithBytes:bytes length:len];
144+
}
145+
142146
std::string NSDataToString(NSData *data) {
143147
return std::string(static_cast<const char *>(data.bytes), data.length);
144148
}

release_build_files/readme.md

+6
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,12 @@ workflow use only during the development of your app, not for publicly shipping
631631
code.
632632

633633
## Release Notes
634+
### Upcoming Release
635+
- Changes
636+
- Analytics (iOS): Add support for
637+
`InitiateOnDeviceConversionMeasurementWithHashedEmailAddress` and
638+
`InitiateOnDeviceConversionMeasurementWithHashedPhoneNumber`.
639+
634640
### 12.0.0
635641
- Changes
636642
- General (Android): Update to Firebase Android BoM version 33.0.0.

0 commit comments

Comments
 (0)