New Requirements from Google to show ads - CMP

@Scott_Harrison has fixed the issue. I’m able to use the consent form for both iOS and Android.

1 Like

I’ve tried setting this up in one Android project, but I’m only getting the aforementioned formStatus of “unavailable” and consentStatus of “unknown”. I’ve tested on Android 9 and 13 devices using the sample code from Solar2D Documentation — Plugins | AdMob | loadConsentForm.

The messages are set up from AdMob’s portal as well. Is there something obvious that I’m missing?

1 Like

I’m also getting “unavailable” and “unknown” on Android. The message is set up on Admob’s portal, with a status of published and everything

if event.phase == "init" then
        local formStatus, consentStatus = admob.getConsentFormStatus()
        printl(">AdMob formStatus", formStatus)
        printl(">AdMob consentStatus", consentStatus)

1 Like

Ok, so I made improvements. You need to call updateConsentForm before getConsentFormStatus
Found that out in Google’s documentation, which states “unknown” for consentStatus comes when that function is not called:

Still, formStatus returns “unavailable” if getConsentFormStatus is called right after updateConsentForm (on the init phase of the event), but if you put a proper delay it then returns “available” and the prompt can be loaded and shown successfully (not sure why)

2 Likes

Yeah, that did it.

Updating the consent form first and then waiting a bit is required in order to get valid consent form statuses.

We’ll need to update the documentation accordingly.

1 Like

Question for @Scott_Harrison,

Does this new consent management system make the optional hasUserConsent parameter in the admob.load() function unnecessary and is all consent logic now handled internally by the AdMob plugin?

Based on the official AdMob SDK docs, “obtained” consent doesn’t define whether the user consented for personalized or non-personalized ads.

1 Like

One more thing to worry about. If the user does not give consent, by clicking “manage options” then “confirm choices” (consent toggles are automatically off), IT STOPS LOADING ADS AT ALL!
Pretty much makes Admob unusable, unless Applovin and Unity Ads do the same.

https://itnext.io/android-admob-consent-with-ump-personalized-or-non-personalized-ads-in-eea-3592e192ec90
https://www.reddit.com/r/androiddev/comments/168tcni/how_are_you_handling_admob_ump_if_a_user_disables/

Some loss in ad rev is nothing compared to EU fines looming. Unity ads has no such stupid restrictions and is GPDR compliant. It’s what I use and the ecpms are much higher than admob assuming you set up a decent waterfall.

Indeed, Unity Ads is an option. The Solar2d plugin doesn’t support banners? Would be a great addition.
Also EU could pressure other ad networks to do the same in the future, Google is the first because it is the most afraid to get sued.

Regadless, the Admob plugin needs a way to check if the consent is given. This link shows how:
https://itnext.io/android-admob-consent-with-ump-personalized-or-non-personalized-ads-in-eea-3592e192ec90

@Scott_Harrison, can it be done?

1 Like

One more problem. I advanced the date on my device to after Jan 16 and the behavior changes. It will automatically try to load the UMP upon calling getConsentFormStatus() (???) and fail, then all calls will get formStatus=unavailable and consentStatus=unknown. If this behavior persists it means you can’t show the dialog and will lose all revenue from EU.

@Scott_Harrison can you confirm if this is something from your implementation or an Admob bug?

As of now this UMP API is to unstale to be used, and unsless this changes the admob plugin is dead. Another option is to implement one of the 3rd party certified Consent management platforms

Re: the date-issue I wouldn’t be surprised if the behavior from their side is currently undefined, but worth asking them.

I have a separate issue. Despite tagging my requests as childSafe and designedForFamilies the UMP SDK sends the Advertising ID to https://fundingchoicesmessages.google.com/. And I get rejected by Google Play.

This forum post describes the issue: https://groups.google.com/g/google-admob-ads-sdk/c/R8ls5sgCYKI

The solution is supposedly to tag consent requests with tag_for_under_age_of_consent (Tag an ad request for EEA, the UK, and Switzerland users for restricted data processing - Google AdMob Help)

But despite doing that Google says I’m transmitting the ad id.

The nuclear option is to remove the permission from the manifest but that will affect all users and probably tank the revenue completely.

Just realized you can check the consent result with plain lua code, no need for internal plugin access

local canShowPersonalizedAds = function()

    local function hasAttribute(input, index)
        if (input == nil) then return false end
        return #input >= index and string.sub(input, index, index) == "1"
    end

    local function hasConsentFor(indexes, purposeConsent, hasVendorConsent)
        for i = 1, #indexes do
            if not hasAttribute(purposeConsent, indexes[i]) then
                printl("hasConsent denied for purpose #" .. indexes[i] )
                return false
            end
        end
        return hasVendorConsent
    end

    local function hasConsentOrLegitimateInterestFor(indexes, purposeConsent, purposeLI, hasVendorConsent, hasVendorLI)
        for i = 1, #indexes do
            local purposeAndVendorLI = hasAttribute(purposeLI, indexes[i]) and hasVendorLI
            local purposeConsentAndVendorConsent = hasAttribute(purposeConsent, indexes[i]) and hasVendorConsent
            local isOk = purposeAndVendorLI or purposeConsentAndVendorConsent
            if not isOk then
                printl("hasConsentOrLegitimateInterestFor: denied for #" .. indexes[i])
                return false
            end
        end
        return true
    end

    local purposeConsent = system.getPreference( "app", "IABTCF_PurposeConsents", "string")
    local vendorConsent = system.getPreference( "app", "IABTCF_VendorConsents","string")
    local vendorLI = system.getPreference( "app", "IABTCF_VendorLegitimateInterests","string")
    local purposeLI = system.getPreference( "app", "IABTCF_PurposeLegitimateInterests","string")

    local googleId = 755
    local hasGoogleVendorConsent = hasAttribute(vendorConsent, googleId)
    local hasGoogleVendorLI = hasAttribute(vendorLI, googleId)
    local hasConsent1 = hasConsentFor({1, 3, 4}, purposeConsent, hasGoogleVendorConsent)
    local hasConsent2 = hasConsentOrLegitimateInterestFor({2, 7, 9, 10}, purposeConsent, purposeLI, hasGoogleVendorConsent, hasGoogleVendorLI)

    return hasConsent1 and hasConsent2
end

If anyone finds a flaw feel free to comment.
Still the weird behavior when you change the date on the device, though, which looks more like a bug than intentional action by Admob

Have not yet tried this, but is for sure concerning. @Scott_Harrison is there a way we can make this available on the plugin. As designed for families apps will be not updatable because of this. From what I’m seeing in the link
https://groups.google.com/g/google-admob-ads-sdk/c/R8ls5sgCYKI 1
It requires

UMP SDK 2.1.0 and [tagging user under age of consent via the isTagForUnderAgeOfConsent API]

I just seen the docs, Solar2D Documentation — Plugins | AdMob | updateConsentForm
Did you set the underage=true and does it make a difference in our case?

I set underage but am currently investigating if it needs to be set at a different position in the init / load sequence

Apologies for unstructured feedback. It appears that setting underage actually causes the form status to remain unavailable.

In my current implementation the form shows up as expected when I set underage false. By toggling underage true, the form does not show up. Makes sense functionality-wise, since the user (child) would not understand the form.

What complicates matters a bit is that I can’t reproduce the transmission of the Ad ID which Google claims is sent to the URL mentioned above, whether or not I set underage. At least I can’t find it in the device log.

It is possible (but not likely) that the build I sent to Google Play had underage = false. So I can submit a new build with underage = true and see if they reject me again. But at this point I’m wondering whether I should just remove the Ad ID from the manifest and scrap the whole UMP/CMP system, since apps for kids in DFF should anyway not send the Ad ID when you set the required flags (see Comply with Google Play’s Families Policy using AdMob - Google AdMob Help)

Realized that AdMob might still require the CMP system, so my next attempted build will be:

  • Underage true. CMP will not show form, but shows consent obtained anyway (?)
  • Disable the Ad ID in the manifest

Actually @perflubron starting api33 you do need to declare ad_id and designed for family section apps must not use it. You need to remove it in manifest

2 Likes

The build passed:

  • Underage true. CMP will not show form, but shows consent obtained
  • Disable the Ad ID in the manifest

NB: Had console warning in publishing overview that manifest did not include Ad ID (picked up from new version), but if I tried to change the declaration saying that I did not use the Ad ID then it would not let me submit (bcs current/live version had it). Solution was to force the update (button to ignore the warning) and then when 100% rollout it was possible to change the declaration.

Have digressed from the topic but perhaps someone finds it relevant