-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
User ID module not getting data from GDPR consent module #5447
Comments
Thanks @EskelCz for writing this up. Prebid team - I've debugged this a bit and I can see that calls to getId() are actually happening before the call to the cmpCallMap, which means the userId module has no way of getting consent. I can't tell why this is happening, though, just that it is. |
I should also add that we had this issue even with TCF 1.1 and our in-house built CMP which was loaded more synchronously, so it's probably a problem specifically with the consentModule->ID5 interaction. |
For whoever picks this up...I think this is more general than just ID5, I think it's the entire userId module that is impacted |
Debugging with the https://demo.cpex.cz/cmp/ it does not seem to be an issue with Prebid.js. Due the the way Prebid.js is integrated in your page, when prebid initializes after initial load (using pbjs.processQueue();), the configs are not set yet. At this point no prebid modules including userId are initialized. When the bid request is made, the configured modules are called in order but userId retains the initial GDPR consent and will not reinitialize. A simple fix for you would be to remove the explicite call to getUserIds() in cpexAnalyticsAdaptor.js and try. One way to achieve this would to be build your cpexAnalyticsAdaptor as a a hook maybe. |
@SKOCHERI Thank you, I wasn't aware that the internal flow wouldn't allow for something like that. |
This came back to bite us. One publisher used a library that reads user ids through prebid (pbjs.getUserIds), which if it runs early enough will basically disable the user id module. This can easily happen without our knowledge. |
I can think of two potential options here, although there are probably several other ways to handle this.
if (pbjs.isUserIdModuleInitialized === true) {
let myUsers = pbjs.getUserIds();
}
let myUsers;
pbjs.getUserIdsWhenAvailable(function(userIds) {myUsers = userIds; })); |
This is potentially relevant to publishers using a script to collect ids for a gam encrypted signal? |
Personally I would prefer a promise that would resolve once the IDs are available |
Yep that works too! |
Patrick and I discussed. Prebid.js must support a way that the page can call the following two functions and be guaranteed that the answer is valid -- i.e. that the module has been initialized:
We propose that the initialization of the userID subsystem is considered 'complete' when these three conditions are met:
The implementation of this could be a callback or promise - at the engineer's discretion. |
At the moment consent data is only resolved at the start of an auction. Coincidentally this will change with #8185; but in the meanwhile, fixing this means that the public ID API ( |
@dgirardi I would say it's better to do nothing than break things in unexpected ways. We even found example of some IDs being read in time and others not. |
This updates the userID module to avoid premature initialization (prebid#5447): - `pbjs.getUserIds` and `pbjs.getUserIdsAsEids` no longer force initialization of the ID system - ID submodules are now initialized after after GDPR consent has been resolved *and* `userSync` configuration has been set - both `pbjs.getUserIds` and `pbjs.getUserIdsAsEids` now accept a callback that, if provided, is scheduled run after all ID submodules have filled in their data. Depending on `userSync` configuration, this may neeed to wait for an AUCTION_END event - `pbjs.refreshUserIds` now forces a fetch regardless of `userSync` config and returns a promise that completes when all ID submodules have filled in their data. `pbjs.refreshUserIds({refresh: false})` will return the promise without reinitialization.
* UserID module: better initialization logic This updates the userID module to avoid premature initialization (#5447): - `pbjs.getUserIds` and `pbjs.getUserIdsAsEids` no longer force initialization of the ID system - ID submodules are now initialized after after GDPR consent has been resolved *and* `userSync` configuration has been set - both `pbjs.getUserIds` and `pbjs.getUserIdsAsEids` now accept a callback that, if provided, is scheduled run after all ID submodules have filled in their data. Depending on `userSync` configuration, this may neeed to wait for an AUCTION_END event - `pbjs.refreshUserIds` now forces a fetch regardless of `userSync` config and returns a promise that completes when all ID submodules have filled in their data. `pbjs.refreshUserIds({refresh: false})` will return the promise without reinitialization. * Add `pbjs.getUserIdsAsync` instead of tacking on callbacks to every other method * Remove out of date typedef
@dgirardi I just tested the new
Any idea what's the holdup? |
@EskelCz what is your configuration? if you have |
No delays. |
@EskelCz - with neither delay, ID submodules start init immediately after the end of the auction. Can you try from the documentation it's not clear to me that these effects are intentional, so we can consider changing it. |
@dgirardi Interesting, that works. WIth the |
@dgirardi I'm wondering, how can userId submodules init after the auction, when the auction itself needs userIds from them? |
it doesn't 'need' them unless the publisher configures it to be so |
@EskelCz auctions work with partially initialized IDs - effectively with what you get from |
@dgirardi Interesting, but that's still weird because why would then getUserIdsAsync be slower, when it should return the same thing - the partially initialized IDs. |
@EskelCz I am confused now, you can get the partial IDs with |
@dgirardi The synchronous version caused a bug (#5447 (comment)) when called before auction, I thought about the async version as just a way to prevent that from happening. Relying on Prebid to figure out it's internal state and timing. |
@EskelCz I think you mean that you're not interested in knowing when init is complete, but only in when Prebid decides it has enough to start the auction? (the combination of gdpr is ready / setConfig was called / locally stored IDs have been retrieved). At the moment that would be equivalent of calling |
@EskelCz if you mean you don't want to call |
@dgirardi I guess you're right, the event handler should suffice. I wasn't sure about the exact event. Thank you |
* UserID module: better initialization logic This updates the userID module to avoid premature initialization (prebid#5447): - `pbjs.getUserIds` and `pbjs.getUserIdsAsEids` no longer force initialization of the ID system - ID submodules are now initialized after after GDPR consent has been resolved *and* `userSync` configuration has been set - both `pbjs.getUserIds` and `pbjs.getUserIdsAsEids` now accept a callback that, if provided, is scheduled run after all ID submodules have filled in their data. Depending on `userSync` configuration, this may neeed to wait for an AUCTION_END event - `pbjs.refreshUserIds` now forces a fetch regardless of `userSync` config and returns a promise that completes when all ID submodules have filled in their data. `pbjs.refreshUserIds({refresh: false})` will return the promise without reinitialization. * Add `pbjs.getUserIdsAsync` instead of tacking on callbacks to every other method * Remove out of date typedef
Bug or unhandled corner case of implementation
Description
We're using OneTrust CMP (to provide us with consent string from TCF API v2) first as a fast loaded stub (tcf.stub.js), which gets filled later on. This works great for bid requests, adapters seem to be getting the consent correctly. Problem comes with passing the string into user ID module ID5. The module is not getting the consent data, therefore it's sending an empty string.
I think it might be caused by the delayed CMP loading, but it's just a guess at the moment.
Steps to reproduce
Test page
We have a demo page to test both the CMP and ID5 sync: https://demo.cpex.cz/cmp/
Open it with network debugger open and (if you don't already have id5 cookie) you should see the id5 server request:
https://id5-sync.com/g/v1/250.json?1puid=&gdpr=0&gdpr_consent=
Expected results
The module should wait for the consent data, the same way as bidder adapters seem to do. The id5 network request should therefore contain
gdpr=1
and the consent string.Actual results
The consent is not present.
Platform details
I'm testing on Prebid 3.23.0, chrome, mac os
The text was updated successfully, but these errors were encountered: