Skip to content

Commit 19f3dbd

Browse files
matinzdmatin-zadeh-dolatabadLyokone
authored
feat(analytics): add consent mode v2 (#12298)
Co-authored-by: matin-zadeh-dolatabad <[email protected]> Co-authored-by: Guillaume Bernos <[email protected]> Co-authored-by: Guillaume Bernos <[email protected]>
1 parent 85a9b18 commit 19f3dbd

File tree

14 files changed

+254
-26
lines changed

14 files changed

+254
-26
lines changed

packages/firebase_analytics/firebase_analytics/android/src/main/java/io/flutter/plugins/firebase/analytics/Constants.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
public class Constants {
1010
public static final String AD_STORAGE_CONSENT_GRANTED = "adStorageConsentGranted";
1111
public static final String ANALYTICS_STORAGE_CONSENT_GRANTED = "analyticsStorageConsentGranted";
12+
public static final String AD_PERSONALIZATION_SIGNALS_CONSENT_GRANTED =
13+
"adPersonalizationSignalsConsentGranted";
14+
public static final String AD_USER_DATA_CONSENT_GRANTED = "adUserDataConsentGranted";
1215
public static final String USER_ID = "userId";
1316
public static final String EVENT_NAME = "eventName";
1417
public static final String PARAMETERS = "parameters";

packages/firebase_analytics/firebase_analytics/android/src/main/java/io/flutter/plugins/firebase/analytics/FlutterFirebaseAnalyticsPlugin.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,10 @@ private Task<Void> setConsent(final Map<String, Object> arguments) {
291291
(Boolean) arguments.get(Constants.AD_STORAGE_CONSENT_GRANTED);
292292
final Boolean analyticsStorageGranted =
293293
(Boolean) arguments.get(Constants.ANALYTICS_STORAGE_CONSENT_GRANTED);
294+
final Boolean adPersonalizationSignalsGranted =
295+
(Boolean) arguments.get(Constants.AD_PERSONALIZATION_SIGNALS_CONSENT_GRANTED);
296+
final Boolean adUserDataGranted =
297+
(Boolean) arguments.get(Constants.AD_USER_DATA_CONSENT_GRANTED);
294298
HashMap<FirebaseAnalytics.ConsentType, FirebaseAnalytics.ConsentStatus> parameters =
295299
new HashMap<>();
296300

@@ -310,6 +314,22 @@ private Task<Void> setConsent(final Map<String, Object> arguments) {
310314
: FirebaseAnalytics.ConsentStatus.DENIED);
311315
}
312316

317+
if (adPersonalizationSignalsGranted != null) {
318+
parameters.put(
319+
FirebaseAnalytics.ConsentType.AD_PERSONALIZATION,
320+
adPersonalizationSignalsGranted
321+
? FirebaseAnalytics.ConsentStatus.GRANTED
322+
: FirebaseAnalytics.ConsentStatus.DENIED);
323+
}
324+
325+
if (adUserDataGranted != null) {
326+
parameters.put(
327+
FirebaseAnalytics.ConsentType.AD_USER_DATA,
328+
adUserDataGranted
329+
? FirebaseAnalytics.ConsentStatus.GRANTED
330+
: FirebaseAnalytics.ConsentStatus.DENIED);
331+
}
332+
313333
analytics.setConsent(parameters);
314334
taskCompletionSource.setResult(null);
315335
} catch (Exception e) {

packages/firebase_analytics/firebase_analytics/example/ios/Flutter/AppFrameworkInfo.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@
2525
<string>arm64</string>
2626
</array>
2727
<key>MinimumOSVersion</key>
28-
<string>11.0</string>
28+
<string>12.0</string>
2929
</dict>
3030
</plist>

packages/firebase_analytics/firebase_analytics/example/ios/Podfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Uncomment this line to define a global platform for your project
2-
platform :ios, '11.0'
2+
platform :ios, '12.0'
33

44
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
55
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

packages/firebase_analytics/firebase_analytics/example/lib/main.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,11 @@ class _MyHomePageState extends State<MyHomePage> {
130130
}
131131

132132
Future<void> _testSetConsent() async {
133-
await widget.analytics.setConsent(adStorageConsentGranted: true);
133+
await widget.analytics.setConsent(
134+
adStorageConsentGranted: true,
135+
adUserDataConsentGranted: true,
136+
adPersonalizationSignalsConsentGranted: true,
137+
);
134138
setMessage('setConsent succeeded');
135139
}
136140

packages/firebase_analytics/firebase_analytics/ios/Classes/FLTFirebaseAnalyticsPlugin.m

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
NSString *const kFLTFirebaseAnalyticsParameters = @"parameters";
1616
NSString *const kFLTFirebaseAnalyticsAdStorageConsentGranted = @"adStorageConsentGranted";
1717
NSString *const kFLTFirebaseAnalyticsStorageConsentGranted = @"analyticsStorageConsentGranted";
18+
NSString *const kFLTFirebaseAdPersonalizationSignalsConsentGranted =
19+
@"adPersonalizationSignalsConsentGranted";
20+
NSString *const kFLTFirebaseAdUserDataConsentGranted = @"adUserDataConsentGranted";
1821
NSString *const kFLTFirebaseAnalyticsUserId = @"userId";
1922

2023
NSString *const FLTFirebaseAnalyticsChannelName = @"plugins.flutter.io/firebase_analytics";
@@ -137,6 +140,10 @@ - (void)resetAnalyticsDataWithMethodCallResult:(FLTFirebaseMethodCallResult *)re
137140
- (void)setConsent:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result {
138141
NSNumber *adStorageGranted = arguments[kFLTFirebaseAnalyticsAdStorageConsentGranted];
139142
NSNumber *analyticsStorageGranted = arguments[kFLTFirebaseAnalyticsStorageConsentGranted];
143+
NSNumber *adPersonalizationSignalsGranted =
144+
arguments[kFLTFirebaseAdPersonalizationSignalsConsentGranted];
145+
NSNumber *adUserDataGranted = arguments[kFLTFirebaseAdUserDataConsentGranted];
146+
140147
NSMutableDictionary<FIRConsentType, FIRConsentStatus> *parameters =
141148
[[NSMutableDictionary alloc] init];
142149

@@ -149,6 +156,17 @@ - (void)setConsent:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResu
149156
[analyticsStorageGranted boolValue] ? FIRConsentStatusGranted : FIRConsentStatusDenied;
150157
}
151158

159+
if (adPersonalizationSignalsGranted != nil) {
160+
parameters[FIRConsentTypeAdPersonalization] = [adPersonalizationSignalsGranted boolValue]
161+
? FIRConsentStatusGranted
162+
: FIRConsentStatusDenied;
163+
}
164+
165+
if (adUserDataGranted != nil) {
166+
parameters[FIRConsentTypeAdUserData] =
167+
[adUserDataGranted boolValue] ? FIRConsentStatusGranted : FIRConsentStatusDenied;
168+
}
169+
152170
[FIRAnalytics setConsent:parameters];
153171
result.success(nil);
154172
}

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

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,44 @@ class FirebaseAnalytics extends FirebasePluginPlatform {
125125
);
126126
}
127127

128-
/// Sets the applicable end user consent state. 'default' value for 'adStorageConsentGranted' & 'analyticsStorageConsentGranted' is 'true'
128+
/// Sets the applicable end user consent state.
129+
/// By default, no consent mode values are set.
130+
///
131+
/// - [adStorageConsentGranted] - Enables storage, such as cookies, related to advertising. (Platform: Android, iOS, Web)
132+
/// - [analyticsStorageConsentGranted] - Enables storage, such as cookies, related to analytics (for example, visit duration). (Platform: Android, iOS, Web)
133+
/// - [adPersonalizationSignalsConsentGranted] - Sets consent for personalized advertising. (Platform: Android, iOS, Web)
134+
/// - [adUserDataConsentGranted] - Sets consent for sending user data to Google for advertising purposes. (Platform: Android, iOS, Web)
135+
/// - [functionalityStorageConsentGranted] - Enables storage that supports the functionality of the website or app such as language settings. (Platform: Web)
136+
/// - [personalizationStorageConsentGranted] - Enables storage related to personalization such as video recommendations. (Platform: Web)
137+
/// - [securityStorageConsentGranted] - Enables storage related to security such as authentication functionality, fraud prevention, and other user protection. (Platform: Web)
138+
///
139+
/// Default consents can be set according to the platform:
140+
/// - [iOS][1]
141+
/// - [Android][2]
142+
/// - [Web][3]
143+
///
144+
/// [1]: https://developers.google.com/tag-platform/security/guides/app-consent?platform=ios#default-consent
145+
/// [2]: https://developers.google.com/tag-platform/security/guides/app-consent?platform=android#default-consent
146+
/// [3]: https://firebase.google.com/docs/reference/js/analytics.md#setconsent_1697027
129147
Future<void> setConsent({
130148
bool? adStorageConsentGranted,
131149
bool? analyticsStorageConsentGranted,
150+
bool? adPersonalizationSignalsConsentGranted,
151+
bool? adUserDataConsentGranted,
152+
bool? functionalityStorageConsentGranted,
153+
bool? personalizationStorageConsentGranted,
154+
bool? securityStorageConsentGranted,
132155
}) async {
133156
await _delegate.setConsent(
134157
adStorageConsentGranted: adStorageConsentGranted,
135158
analyticsStorageConsentGranted: analyticsStorageConsentGranted,
159+
adPersonalizationSignalsConsentGranted:
160+
adPersonalizationSignalsConsentGranted,
161+
adUserDataConsentGranted: adUserDataConsentGranted,
162+
functionalityStorageConsentGranted: functionalityStorageConsentGranted,
163+
personalizationStorageConsentGranted:
164+
personalizationStorageConsentGranted,
165+
securityStorageConsentGranted: securityStorageConsentGranted,
136166
);
137167
}
138168

packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/method_channel/method_channel_firebase_analytics.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform {
7373
Future<void> setConsent({
7474
bool? adStorageConsentGranted,
7575
bool? analyticsStorageConsentGranted,
76+
bool? adPersonalizationSignalsConsentGranted,
77+
bool? adUserDataConsentGranted,
78+
bool? functionalityStorageConsentGranted,
79+
bool? personalizationStorageConsentGranted,
80+
bool? securityStorageConsentGranted,
7681
}) async {
7782
try {
7883
return channel.invokeMethod<void>(
@@ -82,6 +87,11 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform {
8287
'adStorageConsentGranted': adStorageConsentGranted,
8388
if (analyticsStorageConsentGranted != null)
8489
'analyticsStorageConsentGranted': analyticsStorageConsentGranted,
90+
if (adPersonalizationSignalsConsentGranted != null)
91+
'adPersonalizationSignalsConsentGranted':
92+
adPersonalizationSignalsConsentGranted,
93+
if (adUserDataConsentGranted != null)
94+
'adUserDataConsentGranted': adUserDataConsentGranted,
8595
},
8696
);
8797
} catch (e, s) {

packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/platform_interface/platform_interface_firebase_analytics.dart

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,32 @@ abstract class FirebaseAnalyticsPlatform extends PlatformInterface {
167167
}
168168

169169
/// Sets the applicable end user consent state.
170+
/// By default, no consent mode values are set.
171+
///
172+
/// - [adStorageConsentGranted] - Enables storage, such as cookies, related to advertising. (Platform: Android, iOS, Web)
173+
/// - [analyticsStorageConsentGranted] - Enables storage, such as cookies, related to analytics (for example, visit duration). (Platform: Android, iOS, Web)
174+
/// - [adPersonalizationSignalsConsentGranted] - Sets consent for personalized advertising. (Platform: Android, iOS, Web)
175+
/// - [adUserDataConsentGranted] - Sets consent for sending user data to Google for advertising purposes. (Platform: Android, iOS, Web)
176+
/// - [functionalityStorageConsentGranted] - Enables storage that supports the functionality of the website or app such as language settings. (Platform: Web)
177+
/// - [personalizationStorageConsentGranted] - Enables storage related to personalization such as video recommendations. (Platform: Web)
178+
/// - [securityStorageConsentGranted] - Enables storage related to security such as authentication functionality, fraud prevention, and other user protection. (Platform: Web)
179+
///
180+
/// Default consents can be set according to the platform:
181+
/// - [iOS][1]
182+
/// - [Android][2]
183+
/// - [Web][3]
184+
///
185+
/// [1]: https://developers.google.com/tag-platform/security/guides/app-consent?platform=ios#default-consent
186+
/// [2]: https://developers.google.com/tag-platform/security/guides/app-consent?platform=android#default-consent
187+
/// [3]: https://firebase.google.com/docs/reference/js/analytics.md#setconsent_1697027
170188
Future<void> setConsent({
171189
bool? adStorageConsentGranted,
172190
bool? analyticsStorageConsentGranted,
191+
bool? adPersonalizationSignalsConsentGranted,
192+
bool? adUserDataConsentGranted,
193+
bool? functionalityStorageConsentGranted,
194+
bool? personalizationStorageConsentGranted,
195+
bool? securityStorageConsentGranted,
173196
}) {
174197
throw UnimplementedError('setConsent() is not implemented');
175198
}

packages/firebase_analytics/firebase_analytics_web/lib/firebase_analytics_web.dart

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,25 @@ class FirebaseAnalyticsWeb extends FirebaseAnalyticsPlatform {
6767
Future<void> setConsent({
6868
bool? adStorageConsentGranted,
6969
bool? analyticsStorageConsentGranted,
70+
bool? adPersonalizationSignalsConsentGranted,
71+
bool? adUserDataConsentGranted,
72+
bool? functionalityStorageConsentGranted,
73+
bool? personalizationStorageConsentGranted,
74+
bool? securityStorageConsentGranted,
7075
}) async {
71-
throw UnimplementedError('setConsent() is not supported on Web.');
76+
return convertWebExceptions(() {
77+
return _delegate.setConsent(
78+
adStorageConsentGranted: adStorageConsentGranted,
79+
analyticsStorageConsentGranted: analyticsStorageConsentGranted,
80+
adPersonalizationSignalsConsentGranted:
81+
adPersonalizationSignalsConsentGranted,
82+
adUserDataConsentGranted: adUserDataConsentGranted,
83+
functionalityStorageConsentGranted: functionalityStorageConsentGranted,
84+
personalizationStorageConsentGranted:
85+
personalizationStorageConsentGranted,
86+
securityStorageConsentGranted: securityStorageConsentGranted,
87+
);
88+
});
7289
}
7390

7491
@override

packages/firebase_analytics/firebase_analytics_web/lib/interop/analytics.dart

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,42 @@ class Analytics extends JsObjectWrapper<analytics_interop.AnalyticsJsImpl> {
5353
);
5454
}
5555

56+
void setConsent({
57+
bool? adPersonalizationSignalsConsentGranted,
58+
bool? adStorageConsentGranted,
59+
bool? adUserDataConsentGranted,
60+
bool? analyticsStorageConsentGranted,
61+
bool? functionalityStorageConsentGranted,
62+
bool? personalizationStorageConsentGranted,
63+
bool? securityStorageConsentGranted,
64+
}) {
65+
final consentSettings = {
66+
if (adPersonalizationSignalsConsentGranted != null)
67+
'ad_personalization':
68+
adPersonalizationSignalsConsentGranted ? 'granted' : 'denied',
69+
if (adStorageConsentGranted != null)
70+
'ad_storage': adStorageConsentGranted ? 'granted' : 'denied',
71+
if (adUserDataConsentGranted != null)
72+
'ad_user_data': adUserDataConsentGranted ? 'granted' : 'denied',
73+
if (analyticsStorageConsentGranted != null)
74+
'analytics_storage':
75+
analyticsStorageConsentGranted ? 'granted' : 'denied',
76+
if (functionalityStorageConsentGranted != null)
77+
'functionality_storage':
78+
functionalityStorageConsentGranted ? 'granted' : 'denied',
79+
if (personalizationStorageConsentGranted != null)
80+
'personalization_storage':
81+
personalizationStorageConsentGranted ? 'granted' : 'denied',
82+
if (securityStorageConsentGranted != null)
83+
'security_storage':
84+
securityStorageConsentGranted ? 'granted' : 'denied',
85+
}.jsify();
86+
87+
return analytics_interop.setConsent(
88+
consentSettings,
89+
);
90+
}
91+
5692
void setAnalyticsCollectionEnabled({required bool enabled}) {
5793
return analytics_interop.setAnalyticsCollectionEnabled(
5894
jsObject,

packages/firebase_analytics/firebase_analytics_web/lib/interop/analytics_interop.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ external void logEvent(
3232
JSObject? callOptions,
3333
);
3434

35+
@JS()
36+
@staticInterop
37+
external void setConsent(
38+
// https://firebase.google.com/docs/reference/js/analytics.consentsettings.md#consentsettings_interface
39+
JSAny? consentSettings,
40+
);
41+
3542
@JS()
3643
@staticInterop
3744
external void setAnalyticsCollectionEnabled(

0 commit comments

Comments
 (0)