Comments (3)
UMP uses the IAB TCF v2 framework, implying that it writes data on the Shared Preferences to allow ad providers to read them and detect which kind of ads he can provides, as explained by @Skyost .
I am currently using this same mechanism to detect if the user has allowed some of the purposes the IAB TCF v2 gives to detect if I can activate Crashlytics and Analytics.
This is the class I am currently using, if someone is interested :
// All the purposes given by the Funding Choices dialog, found on
// https://iabeurope.eu/iab-europe-transparency-consent-framework-policies/
//
// Purpose 1 - Store and/or access information on a device
// Purpose 2 - Select basic ads
// Purpose 3 - Create a personalised ads profile
// Purpose 4 - Select personalised ads
// Purpose 5 - Create a personalised content profile
// Purpose 6 - Select personalised content
// Purpose 7 - Measure ad performance
// Purpose 8 - Measure content performance
// Purpose 9 - Apply market research to generate audience insights
// Purpose 10 - Develop and improve products
//
// A String in the SharedPreferences file should indicate which one have the user consent.
// This String is stored in a preference file named [package]_preferences
// In the Device File Explorer of Android Studio, you can see where this file is stored
// e.g. for emulator : /data/data/[package]/shared_prefs/[package]_preferences.xml
// You can also open it to see what are the values after you consent to the different
// purposes (or deny them)
import 'package:extended_shared_preferences/SharedPreferences.dart';
enum PurposesConsent {
StoreOrAccessDataOnTerminal,
SelectStandardAds,
CreateAdsPersonalizedProfile,
SelectPersonalizedAds,
CreateContentPersonalizedProfile,
SelectPersonalizedContent,
MeasureAdsPerformance,
MeasureContentPerformance,
UseMarketSearchForAudienceDataGeneration,
DevelopAndImproveProducts
}
class IabTcfV2Reader {
static Future<Map<PurposesConsent, bool>> allConsents(
String packageName) async {
var prefs = SharedPreferences("${packageName}_preferences");
await prefs.loadPersistentStore();
String consents = prefs.getString("IABTCF_PurposeConsents");
String legitimates = prefs.getString("IABTCF_PurposeLegitimateInterests");
// String pubConsents = prefs.getString("IABTCF_PublisherConsent");
// String pubLegitimates =
// prefs.getString("IABTCF_PublisherLegitimateInterests");
Map<PurposesConsent, bool> results = {};
for (int i = 0; i < PurposesConsent.values.length; i++) {
// I think that the 2 bellow variables are the ones I am supposed to check
// to detect if the user has consented the purposes for **my application** (and
// not for ads providers)
int consent = consents.length == PurposesConsent.values.length
? int.tryParse(consents[i])
: 0;
int legitimate = legitimates.length == PurposesConsent.values.length
? int.tryParse(legitimates[i])
: 0;
results[PurposesConsent.values[i]] = consent == 1 || legitimate == 1;
// int pubConsent = pubConsents.length == PurposesConsent.values.length
// ? int.tryParse(pubConsents[i])
// : 0;
// int pubLegitimate = pubLegitimates.length == PurposesConsent.values.length
// ? int.tryParse(pubLegitimates[i])
// : 0;
// results[PurposesConsent.values[i]] = consent == 1 ||
// legitimate == 1 ||
// pubConsent == 1 ||
// pubLegitimate == 1;
}
return results;
}
static Future<bool> hasConsented(
String packageName, PurposesConsent purpose) async {
return (await allConsents(packageName))[purpose];
}
static Future<bool> isCrashlyticsAllowed(String packageName) async {
var consents = await IabTcfV2Reader.allConsents(packageName);
bool allowCrashlytics =
consents[PurposesConsent.StoreOrAccessDataOnTerminal] &&
consents[PurposesConsent.DevelopAndImproveProducts];
return allowCrashlytics;
}
static Future<bool> isAnalyticsAllowed(String packageName) async {
var consents = await IabTcfV2Reader.allConsents(packageName);
bool allowAnalytics =
consents[PurposesConsent.StoreOrAccessDataOnTerminal] &&
consents[PurposesConsent.DevelopAndImproveProducts] &&
consents[PurposesConsent.MeasureContentPerformance];
return allowAnalytics;
}
static Future<bool> unpersonalizedAdsAllowed(String packageName) async {
return await IabTcfV2Reader.hasConsented(
packageName, PurposesConsent.StoreOrAccessDataOnTerminal);
}
}
I am using extended_shared_preferences to read the values of IAB TCF v2 written in SharedPreferences.
Some important notes :
- I am not sure that what I am doing is 100% legal, my implementation may be wrong
- I don't always understand the values stored in the IABTCF_ keys in the SharedPreferences. Sometimes, they just seem weird and there are quite some discussions about it around the web. Things start getting tricky when the user clicks on the "Manage preferences" button. If he clicks on "Agree", it should be OK but it will depend a lot on which purposes you choose on the Funding Choices website.
- My app is not yet on production. Some users seem to not have ads depending on the choices user makes in the Funding Choices dialog. I am currently blocking my app while the user has not yet added at least the minimum rights to let admob serve unpersonalized ads.
from flutterfundingchoices.
Hi !
Well, I don't know since all these GDPR things are a mess for me (and I'm absolutely not an expert). But it should work with Crashlytics and Analytics, from my understanding.
Having one more dialog seems overkill with all the things the Funding Choices asks...
For example, if you're developping on iOS and want to use AdMob, you should implement both Apple and GDPR dialogs. So it's pretty much the same scenario, isn't it ? 😄
from flutterfundingchoices.
It's a mess for me aswell 😅
I think I'll set analytics and Crashlytics based on the fact that the user has agreed for personalized ads... Not perfect but I don't want to have one dialog for the Funding Choices + authorization dialogs for camera or things like that + one for Apple if it's on iOS + one for Crashlytics and Analytics... And I might want to show my own app dialogs aswell 🤦♂️
I thought that the UMP SDK would allow us to know which checkbox the user had checked and your package made it readable but I just took a look in the UMP SDK and they just provide the ConsentStatuts and ConsentType that you already provide.
No improvements to do on the Dart package since they are not available in the UMP SDK 🤷
from flutterfundingchoices.
Related Issues (15)
- Always returning ConsentType.UNKNOWN HOT 8
- After adding, can't run app on iOS Simulator M1 HOT 6
- Ability to use the setDebugGeography() method HOT 9
- IOS build error: Parse Issue: Module flutter_funding_choices not found HOT 2
- Issue during the upgrade to 0.3.0+1 HOT 1
- Question about how the consent dialog is triggered HOT 2
- Update UMP SDK to latest 2.0.0 version
- Android build failure after updating to Kotlin Gradle plugin 1.8.21 HOT 2
- Unhandled exception
- Where does Funding Choices store the preferences?
- consentInfo always returns ConsentStatus.OBTAINED
- Error 1.1 HOT 6
- Fatal Error on iOS HOT 4
- Can't find the import HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from flutterfundingchoices.