Skip to content

Privacy and Consent UMP

Alessandro Morvillo edited this page Aug 2, 2026 · 1 revision

Privacy and Consent with UMP

Google User Messaging Platform (UMP) must run before Google Mobile Ads is initialized or any ad request is made.

Recommended flow

App starts
  -> refresh consent information
  -> load and show a required consent form
  -> evaluate CanRequestAds
  -> initialize Mobile Ads
  -> load ads

Run the refresh on every app launch. Do not assume that a status cached from a previous launch is still valid.

MAUI

IAdMobConsentService is registered by UseAMDevITAdMobWrapper() on every MAUI target.

public sealed class AdMobStartup(IAdMobConsentService consentService)
{
    public async Task<bool> InitializeAsync(
        CancellationToken cancellationToken = default)
    {
        if (!consentService.IsSupported)
        {
            // UMP is not available on this platform. Skip the advertising
            // startup and let the application continue with its fallback UI.
            return false;
        }

        bool canRequestAds;

        try
        {
            ConsentGatheringResult result = await consentService.GatherConsentAsync(
                cancellationToken: cancellationToken);
            canRequestAds = result.CanRequestAds;
        }
        catch (ConsentException exception) when (exception.CanRequestAds == true)
        {
            // Refresh failed, but the previous consent state still permits ads.
            canRequestAds = true;
        }

        if (!canRequestAds)
            return false;

        string applicationId = OperatingSystem.IsAndroid()
            ? "ca-app-pub-XXXXXXXXXXXXXXXX~YYYYYYYYYY"
            : string.Empty;

        await consentService.InitializeAsync(applicationId, cancellationToken);
        return true;
    }
}

The application ID argument is required on Android. iOS ignores it and reads GADApplicationIdentifier from Info.plist.

Availability and state

Property Android/iOS Windows/Mac Catalyst
IsSupported true false
CanRequestAds Native UMP state true
IsInitialized Native SDK state true
CurrentConsentInformation Native snapshot Neutral NotRequired snapshot

Desktop methods are safe no-ops and log that consent is unavailable. They do not throw, including when called with an already-cancelled token.

Native Android async flow

AdMobManager manager = AdMobManager.Instance;

ConsentGatheringResult result = await manager.GatherConsentAsync(this);
if (!result.CanRequestAds)
    return;

await manager.InitializeAsync(
    this.ApplicationContext!,
    "ca-app-pub-XXXXXXXXXXXXXXXX~YYYYYYYYYY");

Native iOS async flow

AdMobManager manager = AdMobManager.Instance;

ConsentGatheringResult result = await manager.GatherConsentAsync(this);
if (!result.CanRequestAds)
    return;

await manager.InitializeAsync(this);

Privacy options

When ConsentGatheringResult.PrivacyOptionsRequired is true, expose a persistent privacy entry point in the application's settings:

await consentService.ShowPrivacyOptionsFormAsync(cancellationToken);

You can also inspect:

ConsentInformationSnapshot? snapshot = consentService.CurrentConsentInformation;

bool privacyEntryRequired =
    snapshot?.PrivacyOptionsRequirementStatus ==
    PrivacyOptionsRequirementStatus.Required;

Other operations

  • UpdateCurrentConsentInformationAsync refreshes UMP state without running the combined gather flow.
  • LoadAndShowConsentFormIfRequiredAsync handles only the required form.
  • ShowPrivacyOptionsFormAsync opens the user's privacy controls.
  • ResetConsentForTesting clears consent state for development tests.

Under-age and debug settings

ConsentRequestOptions options = new(
    TagForUnderAgeOfConsent: false,
    DebugParameters: new ConsentDebugParameters(
        ConsentDebugGeography.Eea,
        "TEST-DEVICE-HASH"));

ConsentGatheringResult result = await consentService.GatherConsentAsync(options);

Never include debug geography or test-device identifiers in a production build.

Error handling

ConsentException exposes:

  • ErrorCode and Message;
  • nullable CanRequestAds state available when the failure occurred;
  • nullable PrivacyOptionsRequired state.

Only continue loading ads after an error when CanRequestAds == true.

Clone this wiki locally