admob-plus / admob-plus

Trustable AdMob Plugin for Cordova, Capacitor, Ionic, React Native
https://admob-plus.github.io
MIT License
360 stars 150 forks source link

consentStatus Issue, consent.canRequestAds returning incorrect value #647

Open ngdevr opened 4 months ago

ngdevr commented 4 months ago

In Google UMP Popup, when I click on "Manage Options" and then click on "Confirm Choices" without changing any default selection, and then call to consent.canRequestAds() is returning true but it should return false since user did not consent to anything. Afterwards call to load any ad fails with following error which is the correct behavior on Admob side

image

cordova-plugin-consent version 3.0.0-alpha.6 UMP_VERSION 2.1.0

1n3JgKl9pQ6cUMrW commented 4 months ago

When someone tries to manage the options and simply confirmed, without doing anything, no single ad will ever be served.

So the consent works as a solid, full blown ad-blocker from that moment.

This situation is know by Google and by default, because they need at least one cookie or whatever to serve an ad.

Strictly through, you can request ads that are not personalized (NPA = 1), but this doesn't work.

Even when requesting fully anonymous ads, no ad is given in return.

We should just prepare to loose large amounts of ad incomes, I think.

1n3JgKl9pQ6cUMrW commented 4 months ago

In addition, you can request ads after the consent is denied, because the end user had given consent about not willing to see (personal) ads.

So consent is given, and that's what's is all about.

Stupid, yes.

ngdevr commented 4 months ago

Ok, I thought we should be able to not load the ads if consent was denied, but since the consent.canRequestAds() is returning true, we will be sending unnecessary request to Admob only to be denied. Am I correctly interpreting current scenario? My problem was that shouldn't consent.canRequestAds() just return false, if the consent was obtained but not given.

1n3JgKl9pQ6cUMrW commented 4 months ago

By law, you can request ads, or at least try to, because the user has given consent.

If the consent is YES or NO, doesn't matter; you have the consent.

Technically you can request for Non Personal Ads by using the parameter NPA=1 in your ad-request-setting, but Google did mention this won't work because even then you need at least a stupid cookie.

ngdevr commented 4 months ago

Thanks for the explanation, I would then just keep sending the requests to Admob and let them decide what do they want to do with the request. If they decide in future to show Non-Personal Ads then at least I won't have to fix anything at my end and release a new version.
Hope, Google just fixes the popup and give us the option to keep minimally required options selected by default.

1n3JgKl9pQ6cUMrW commented 4 months ago

That's at least how I got it, by my own debugging, testing and reading on the fora.

When someone says "no!" you can add the npa=1 parameter in your request.

That will force Non-Personal Ads.

I did not succeed to get / fetch those NPA-ads, but at least you can try.

See : https://admob-plus.github.io/docs/cordova/consent#forward-consent

image

1n3JgKl9pQ6cUMrW commented 4 months ago

One more thing.

The plugin can not see which choice a user did make, only that the choice was made (at least, that's what I understand from it).

So if you want to "read" a formerly set the preference of a user, you can't.

If you want to see if you have to serve NPA-ads, I use this plugin;

https://github.com/MrRotella/cordova-plugin-gdpr-choices

It can read / get / fetch the exact settings a user did set, when giving consent.

ngdevr commented 4 months ago

ok, from this other plugin, I believe if canShowPersonalizedAds() is false but canShowAds() is true then we should serve NPA-ads. Correct?

1n3JgKl9pQ6cUMrW commented 4 months ago

Sounds logic to me, but I haven't tried yet.

I have to implement it first, which I will do later on this year.

ngdevr commented 4 months ago

Some options that are missing in admob-plus consent plugin is the capability to check for EEA. In absence of a check for request coming from an EEA country, if the consent was obtained and denied in EEA country but the person is now in NonEEA country, then getConsentStatus() will still return status as Obtained which means no ads so just to check whether or not, we are making a request from a NonEEA country, we will need another plugin like MrRotella.

admob-plus consent plugin returns consent as NotRequired for NonEEA country but once a consent was set for EEA country for that user, it will always return consent as Obtained even for requests coming from NonEEA countries. The first step should be to simply check whether or not request is coming from an EEA country before executing all this consent specific code.

EMI-INDO commented 4 months ago
1n3JgKl9pQ6cUMrW commented 4 months ago

just to check whether or not, we are making a request from a NonEEA country, we will need another plugin like MrRotella.

You can also set the message / consent to appear in EU-countries only;

image

You can do that in Googles back-end.

That way, a non-EU user will never see the form. So when someone does see the form, he / she must be inside an EU country in the first time.

  • TCString expires after 13 months, ads will not be displayed.

Interesting, thanks for the info.

I will clear the preferences every 12 months, using consent.reset(); which is a "hidden" (not documented) feature for the admob-plus plugin at reset.

image

ngdevr commented 4 months ago

Since Google is also asking to give users an option to change his/her previous consent, this is where consent.reset() comes. I have tested it and works fine. Before launching the form, I reset the consent and user shall now give a new consent.

1n3JgKl9pQ6cUMrW commented 4 months ago

Since Google is also asking to give users an option to change his/her previous consent, this is where consent.reset() comes. I have tested it and works fine. Before launching the form, I reset the consent and user shall now give a new consent.

It works great; I have programmed a workflow where users who say "yes" are reset after 12 months (because 13 months is the absolute limit).

And users who say "no" are reset every month (because "no" will act as an 100% ad-blocker for my app).

It is illegal to block or "cripple" the app for users who say "no", but it is allowed to reset their consent now and than.

Also, you must build in an option in your app where users can both SEE and RESET their consent preferences at any moment.

ngdevr commented 4 months ago

Resetting consent of users who say "no" every month looks like a very good idea. So does resetting consent every 12 months for users who say "yes". My other question is what happens when the consent expires. Do we get the consentStatus as "Obtained" or "Required". If we get the correct consentStatus after 13 months expiration, we probably won't have to reset for users who said "yes".

hooliapps commented 4 months ago

Since Google is also asking to give users an option to change his/her previous consent, this is where consent.reset() comes. I have tested it and works fine. Before launching the form, I reset the consent and user shall now give a new consent.

It works great; I have programmed a workflow where users who say "yes" are reset after 12 months (because 13 months is the absolute limit).

And users who say "no" are reset every month (because "no" will act as an 100% ad-blocker for my app).

It is illegal to block or "cripple" the app for users who say "no", but it is allowed to reset their consent now and than.

Also, you must build in an option in your app where users can both SEE and RESET their consent preferences at any moment.

Thanks for info, can you provide code example please ? (how you implemented this)

1n3JgKl9pQ6cUMrW commented 4 months ago

The code is, somewhat, complex because I do check lot's of thing before resetting it (from a distance server).

But I user MrRotella's plugin (Android only) to read the users preferences.

https://github.com/MrRotella/cordova-plugin-gdpr-choices

Once a user has given consent, but denied ads (which is the most possible situation, besides giving consent and allowing ads), I do reset the preferences (once a month, automatically set by the server my app uses to communicate with).

At the end it's something like "when user says 'no', I do reset it's preferences, so he is forced to give consent again".

Hopefully this nagging every month will result in 2 or 3% more users that accept the ads (most of them will say "no" by incident, I think, since the whole process of consent is a mass).


See some more detailed info in this thread;

https://github.com/admob-plus/admob-plus/issues/601#issuecomment-1702578477

1n3JgKl9pQ6cUMrW commented 4 months ago

Resetting consent of users who say "no" every month looks like a very good idea. So does resetting consent every 12 months for users who say "yes". My other question is what happens when the consent expires. Do we get the consentStatus as "Obtained" or "Required". If we get the correct consentStatus after 13 months expiration, we probably won't have to reset for users who said "yes".

You are forced by Google to reset it, because after 13 months Google does reset it themself.

When the consent is reset and not given again (or archived, because too old), Google will stop serving ads at once.

So better be sure to reset it every x-months.

ngdevr commented 4 months ago

But I user MrRotella's plugin (Android only) to read the users preferences.

How do you read the user preferences? I see only three methods available but none of them seem to be returning user preferences.

1n3JgKl9pQ6cUMrW commented 4 months ago
/* 1. does GDPR apply */

$gdpr_tmp = await cordova.Gdpr.isGdpr();
$gdpr_1 = $gdpr_tmp.hasOwnProperty( 'value' ) ? parseInt( $gdpr_tmp[ 'value' ] ) : 'unknown';
console.log( 'GDPR apply : ' + $gdpr_1 );

/* 2. Ads allowed */

$gdpr_tmp = await cordova.Gdpr.canShowAds();
$gdpr_2 = $gdpr_tmp[ 'value' ] === true ? 1 : -1;
console.log( 'Can show ads : ' + $gdpr_2 );

/* 3. Personal ads allowed */

$gdpr_tmp = await cordova.Gdpr.canShowPersonalizedAds();
$gdpr_3 = $gdpr_tmp[ 'value' ] === true ? 1 : -1;
console.log( 'Show personal ads ' + $gdpr_3 );
ngdevr commented 4 months ago

Ok, but how do you know that consent is not given? In admob-plus consent plugin, canShowAds returns true even when consent is not given which means canShowAds is returning true as soon as consent is obtained (irrespective of yes or no). I believe MrRotella's plugin will return the same thing. Correct?

1n3JgKl9pQ6cUMrW commented 4 months ago

This is not a helpdesk, please code yourself.

And the data MrRotella does return is always different;


1. consent given / allow ads

image

2. consent given / no allow ads

image

3. no consent given / no allow ads

image

ngdevr commented 4 months ago

Thanks, sorry to have pestered you with too many questions. I was simply trying to get a head start since you have already used MrRotella's plugin. I am definitely going to test the plugin for all scenarios according to my requirements. Your help so far is very much appreciated.

1n3JgKl9pQ6cUMrW commented 4 months ago

You're welcome.

I did hours (days / weeks) research and coding for this "stupid" consent thing.

In the end, I decided to build a complete new Cordova app from scratch (see the screenshots above).

This app does nothing, besides loading an ad, trying to fetch the GDPR-settings and show the GDPR-form when needed.

So I know "it does work", but I also now "it's a pain in the *ss" to get it done.

Once my test-app was finished, I migrated the code from that app to my real apps and did test every thing once again (in the real app environment).

SamirHodzic commented 3 months ago

Just extension to this topic for everyone suffering of finding additional data of what exactly needs to be done and in which manner, related to the npa=1 - seems like there is no need anymore to explicitly provide it when requesting ads and that UMP will handle it by itself;

According to the person from the Mobile Ads SDK Team, the consent results are stored in UserDefaults (SharedPreference in Android) and AdMob SDK uses it without any publishers' additional action.

https://groups.google.com/g/google-admob-ads-sdk/c/I6j0Pr-_ziY/m/VOH06zsWAQAJ