Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to know if user selected "Do not consent"? #23

Closed
tarouboy opened this issue Jan 1, 2022 · 15 comments
Closed

How to know if user selected "Do not consent"? #23

tarouboy opened this issue Jan 1, 2022 · 15 comments

Comments

@tarouboy
Copy link

tarouboy commented Jan 1, 2022

Currently, after UMP.showConsentForm(), no matter the user selected "Consent" or "Do not consent", the returned result is CONSENT_STATUS.OBTAINED.

So when requesting Ads from Admob, how do I know if I should pass requestNonPersonalizedAdsOnly?
Or I don't have to coz' Google already stored the user's preference?

Thank you!

@tarouboy
Copy link
Author

tarouboy commented Jan 1, 2022

Sorry for opening the issue, I found this from stackoverflow.

In case anyone else is interested:
https://stackoverflow.com/questions/63464270/how-to-request-non-personalized-admob-ads-with-the-new-unified-messaging-platfor

@tarouboy tarouboy closed this as completed Jan 1, 2022
@scaralfred
Copy link

Hello. Did you find a way to handle this case?
Since we can't know if the user has given consent or not, it means we can't fill the boolean "requestPersonalizedAds" when requesting ads... And as far as I understand, that's developer's responsibility.
What should we do?

@birgernass
Copy link
Owner

You can read the IABTCF_TCString key from standardUserDefaults / SharedPreferences and decode it with a library like @iabtcf/core to evaluate all user choices.

@scaralfred
Copy link

scaralfred commented Mar 16, 2022

Thanks, @birgernass I'll definitely do that!
Do you know the same solution for iOS as well?
As far as I understand, even if on iOS we use ATT, we should still show UMP consent... so the issue presents itself on this platform too. Where should we read the IABTCF_TCString in this case?

@scaralfred
Copy link

I think I found it. For iOS we should use NSUserDefaults.

@birgernass
Copy link
Owner

birgernass commented Mar 16, 2022

Yes, exactly. On iOS you can do
[[NSUserDefaults standardUserDefaults] objectForKey:@"IABTCF_TCString"]
and on Android PreferenceManager.getDefaultSharedPreferences(reactContext).getString("IABTCF_TCString", null). I assume there are libraries to read these preferences as well.

@VictorioMolina
Copy link

@birgernass @scaralfred doesn't AdMob handle this automatically? Do we need to make sure if ads should be shown or which type of ads to display (personalised or not personalised)?

@birgernass
Copy link
Owner

The information is encoded in the TCString which is send with the ad request. So yes, this is handled automatically. Google won't serve any ads if a user declined consent.

There are other reasons to evaluate the consent though, e.g. to offer a subscription as an alternative to users who declined. While I don't intend to add functionality to inspect the individual consent choices to this library, I added such a method to the react-native-google-mobile-ads repository.

@VictorioMolina
Copy link

VictorioMolina commented Nov 18, 2022

@birgernass Thanks for the response. In my case I am using react-native-google-mobile-ads. But I am a bit confused...

I am handling the EEA consent scenario, as indicated here.

When testing the following code:

const requestAdsConsent = async () => {
  const consentInfo = await AdsConsent.requestInfoUpdate({
    tagForUnderAgeOfConsent: false,
    testDeviceIdentifiers: ["EMULATOR"],
    ...__DEV__ && { debugGeography: AdsConsentDebugGeography.EEA },
  });

  if (
    consentInfo.isConsentFormAvailable &&
    consentInfo.status === AdsConsentStatus.REQUIRED
  ) {
    const { status } = await AdsConsent.showForm();

    consentInfo.status = status;
  }

  return consentInfo;
};

const initializeAdmob = async () => {
  // Request the respective consent to EEA-based users
  await requestAdsConsent();

  // Configure the ads requests
  await mobileAds().setRequestConfiguration({
    maxAdContentRating: MaxAdContentRating.MA,
    tagForChildDirectedTreatment: false,
    tagForUnderAgeOfConsent: false,
    testDeviceIdentifiers: ["EMULATOR"],
  });

  // Initialize the AdMob service
  await mobileAds().initialize();
};

I get the ATT form (configured in the AdMob SDK) being displayed on my emulator. What if I press the 'do not consent' option? I mean, if I use this config for requesting ads:

const ADS_REQUEST_OPTIONS = {
  requestNonPersonalizedAdsOnly: false, // <------
  keywords: ADMOB_KEYWORDS,
};
  1. DO I NEED TO TOGGLE THE requestNonPersonalizedAdsOnly PROPERTY TO true? Or is it ok to use requestNonPersonalizedAdsOnly: false, because AdMob will automatically ignore the field and send non personalized ads only?

  2. DO I NEED TO AVOID REQUESTING THE AD IF THE USER DOESN'T GRANT CONSENT TO "Store and/or access information on a device"?

Are those points automatically handled by Google Admob?

@VictorioMolina
Copy link

VictorioMolina commented Nov 18, 2022

@birgernass So, as you mentioned to me:

The information is encoded in the TCString which is send with the ad request. So yes, this is handled automatically. Google won't serve any ads if a user declined consent.

Does this mean that I do not need to change the requestNonPersonalizedAdsOnly field based on the user consent status?

The opposite is done here, at line 122.

@birgernass
Copy link
Owner

I personally don't work with AdMob, but with AdManager, of which I am also not an expert, so my answers should be taken with a grain of salt.

Searching for requestNonPersonalizedAdsOnly only surfaces 3rd party libraries and no official docs from Google. I assume that the flag is deprecated and pre-dates the introduction of the UMP SDK and is therefore no longer needed.

You also don't have to avoid requests without consent. There is no penalty for requesting ads, as far as I'm aware, you just won't get any ads served.

@VictorioMolina
Copy link

@birgernass https://developers.google.com/admob/ump/android/quick-start#forward-consent It seems that, for react-native-google-mobile-ads, because of this line, we need to dynamically change the requestNonPersonalizedAdsOnly value. Thank you.

@birgernass
Copy link
Owner

I see, thanks for clarifying!

@VictorioMolina
Copy link

VictorioMolina commented Nov 20, 2022

Hey @birgernass, I'm here again, sorry. As you told me, you are the person who developed this method.

Well, this works great with EEA and GDPR consent. By the way, if we use personalized ads in our app, the user has to grant consent to the IDFA form (ATT). UMP will only display the ATT form for users outside the EEA, without including the GDPR one in the flow.

As we have to be able to let AdMob know if the user granted consent or not (to show personalized ads), doing the following for users that are NOT IN THE EEA will result in a problem:

  const handlePersonalizedAds = async () => {
    const choices = await AdsConsent.getUserChoices();

    console.log(JSON.stringify(choices, null, 2)); // All is FALSE for the ATT consent form, if no GDPR consent form displayed. <----

    const personalizedAds = choices.storeAndAccessInformationOnDevice &&
      choices.selectBasicAds &&
      choices.createAPersonalisedAdsProfile &&
      choices.selectPersonalisedAds &&
      choices.measureAdPerformance &&
      choices.applyMarketResearchToGenerateAudienceInsights &&
      choices.developAndImproveProducts;

    setShouldServePersonalizedAds(personalizedAds);
  };

const requestAdsConsent = async () => {
    const consentInfo = await AdsConsent.requestInfoUpdate({
      tagForUnderAgeOfConsent: false,
      testDeviceIdentifiers: [TEST_DEVICE_ID],
      // Always ensure debug information is removed for production apps!
      ...__DEV__ && { debugGeography: AdsConsentDebugGeography.NOT_EEA },
    });

    if (
      consentInfo.isConsentFormAvailable &&
      consentInfo.status === AdsConsentStatus.REQUIRED
    ) {
        await AdsConsent.showForm(); // This shows ATT (on iOS) + GDPR (for EEA-based users) <-------
    }

    await handlePersonalizedAds();
  };

So, imagine that someone, from outside the EEA and using iOS, grants the respective permissions to the ATT form, which is displayed when calling AdsConsent.showForm(). For this scenario, all the properties returned from AdsConsent.getUserChoices() are false, which I think is not the expected behavior.

invertase/react-native-google-mobile-ads#185

Do you know something about this?

@birgernass
Copy link
Owner

I'm not sure which behaviour people would actually expect. In the end the user did not give consent to those individual choices and they are not part of Apple's App Tracking Transparency framework. So one could argue that the false values are indeed expected. But the whole consenting flow could certainly be improved and the discussion is fair to have. I wouldn't have it here though as the method is not part of this repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants