Giter VIP home page Giter VIP logo

Comments (3)

apalala-dev avatar apalala-dev commented on July 23, 2024 2

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.

Skyost avatar Skyost commented on July 23, 2024

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.

apalala-dev avatar apalala-dev commented on July 23, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.