Zum Hauptinhalt springen

Wie man AdMob-GDPR-Zustimmung in Capacitor handhabt

Man handhabt AdMob-GDPR-Zustimmung in einer Capacitor-Anwendung mit Googles UMP SDK: Zustimmungsformular, Datenschutzeinstellungen, ATT-Anforderung, Debug-Geographie und Fehlerbehandlung, mit code.

Artikelcredits

Martin Donadieu

Schreiber

Valeria

Reviewer

Jordan

Editor

Wie man AdMob GDPR-Zustimmung in Capacitor handhabt

Um AdMob GDPR-Zustimmung in einer Capacitor-Anwendung zu handhaben, verwenden Sie das Google-Benutzermeldungssystem (UMP) SDK: Fordern Sie Zustimmungsdaten bei jedem Start an, zeigen Sie das Zustimmungsformular, wenn erforderlich, und initialisieren Sie Werbung nur, wenn canRequestAds ist wahr. Sie benötigen auch einen Datenschutzoptionen-Einstiegspunkt, damit Benutzer ihre Wahl ändern können, und auf iOS sollte der UMP-Flow vor dem App-Tracking-Transparenz-Anfragen-Flow erfolgen. Diese Anleitung zeigt den vollständigen Flow mit zwei Konfigurationen: einer Plugin-Konfiguration, die UMP in JavaScript einhüllt, und einer kleinen nativen Zustimmungsbrücke. @capgo/capacitor-admob Was UMP tut und warum AdMob es erfordert

Was UMP tut und warum AdMob es benötigt

Since January 2024, Google requires publishers that serve ads to users in the EEA, the UK and Switzerland to use a Google-certified consent management platform (CMP) integrated with the IAB Transparency and Consent Framework (TCF). The UMP SDK is Google’s own certified CMP, free and built into the AdMob console.

UMP tut drei Dinge für Sie:

  1. Erkennen, ob der Benutzer in einer Region ist, in der eine Zustimmung erforderlich ist.
  2. Zeigt die von Ihnen in AdMob konfigurierte Zustimmungsnachricht in der Sprache des Benutzers an.
  3. Speichert die Benutzerentscheidungen als TC-String auf dem Gerät (die Standard- IABTCF_ Schlüssel in UserDefaults auf iOS und SharedPreferences auf Android), die die Google Mobile Ads SDK und die Mediationspartner bei der Anforderung von Anzeigen lesen.

Sie können auch UMP für die US-Bundesstaatsdatenschutzvorschriften verwenden, die AdMob als „US-Staaten“-Nachrichten bezeichnet, aus demselben Konsole.

Schritt 1: Erstellen Sie die Nachrichten in AdMob

Gehe in das AdMob-Konsole In der AdMob-Konsole gehen Sie zu :

  • Erstelle ein Erstellen Sie eine europäische Vorschriften Nachricht (GDPR). Wählen Sie, welche Apps davon betroffen sind, die Sprachen und Ihre Liste der Werbepartner.
  • Optionell eine US-Bundesstaaten message.
  • On iOS eine IDFA-Erklärung Nachricht erstellen, wenn Sie die App-Tracking-Transparenz-Anforderung stellen möchten. UMP zeigt sie vor dem System-ATT-Angebot an.
  • Die Nachrichten veröffentlichen. Eine nicht veröffentlichte Nachricht wird nie angezeigt.

Wenn die Form in Ihrer App später nie erscheint, ist eine nicht veröffentlichte oder nicht zugewiesene Nachricht das erste, was Sie überprüfen sollten.

Schritt 2: Bestimmen Sie die Reihenfolge der Aktionen

The order that works for most apps:

  1. Die App startet.
  2. Bereits bei jedem Start die Zustimmungsinformationen aktualisieren.
  3. Wenn erforderlich, laden und zeigen Sie das Einwilligungsfomular.
  4. Wenn canRequestAds ist wahr, starten Sie die Mobile Ads SDK und laden Sie Anzeigen.
  5. Zeigen Sie ein „Datenschutz-Einstellungen“-Eintrag in Ihrem Einstellungs-Menü, wenn UMP sagt, dass Datenschutzeinstellungen erforderlich sind.

Google ermöglicht auch, dass die Mobile Ads SDK parallel zum Einwilligungsantrag gestartet werden können, wenn canRequestAds war bereits wahr von einer vorherigen Sitzung. Das verkürzt die Zeit bis zum ersten Anzeigen für wiederkehrende Benutzer.

Option A: ein Plugin, das UMP in JavaScript einhüllt

@capacitor-community/admob (Version 8 unterstützt Capacitor 8) bietet UMP-Methode direkt an: requestConsentInfo, showConsentForm, showPrivacyOptionsForm und resetConsentInfo.

bun add @capacitor-community/admob
bunx cap sync
import {
  AdMob,
  AdmobConsentStatus,
  AdmobConsentDebugGeography,
} from '@capacitor-community/admob';

export async function initAdsWithConsent(isDebug: boolean) {
  await AdMob.initialize();

  let info = await AdMob.requestConsentInfo(
    isDebug
      ? {
          debugGeography: AdmobConsentDebugGeography.EEA,
          testDeviceIdentifiers: ['YOUR_TEST_DEVICE_ID'],
        }
      : undefined,
  );

  if (info.isConsentFormAvailable && info.status === AdmobConsentStatus.REQUIRED) {
    info = await AdMob.showConsentForm();
  }

  // The enum value is the string 'REQUIRED'
  const showPrivacyEntry = String(info.privacyOptionsRequirementStatus) === 'REQUIRED';

  return { canRequestAds: info.canRequestAds, showPrivacyEntry };
}

export async function openPrivacyOptions() {
  await AdMob.showPrivacyOptionsForm();
}

Dieses Plugin ist die einzige Ausnahme von der Reihenfolge oben: Sein README erfordert AdMob.initialize() vorher requestConsentInfo()und auf iOS kann die Zustimmungserklärung nicht vorhergezeigt werden, bis initialize() hat gelaufen. initialize() startet den SDK, lädt jedoch keine Anzeigen, daher ist die Regel, nie eine Anzeige zu laden, bis canRequestAds is true. If you need the SDK to stay stopped until the user has answered, use Option B, where consent runs before AdMob.start().

Überprüfen canRequestAds vor jeder Anzeigenaufladung, nicht nur bei der Startphase, da der Benutzer die Einwilligung aus der Datenschutzeinstellungenform zurückziehen kann.

Option B: @capgo/capacitor-admob mit einem nativen UMP-Bridge

@capgo/capacitor-admob bietet Ihnen AdMob.start(), Anzeigenanforderungskonfiguration, Banner, Interstitiale, Reward- und Reward-Interstitiale-Anzeigen, sowie iOS-Tracking-Autorisierung. Es wrappt UMP nicht, daher fügen Sie ein kleines, lokal im App-Ordner installiertes Plugin hinzu, das den Einwilligungsvorgang ausführt, bevor Sie AdMob.start().

bun add @capgo/capacitor-admob
bunx cap sync

den UMP SDK hinzufügen.

  • iOS: fügen Sie Googles GoogleUserMessagingPlatform Paket mit Swift Package Manager (Capacitor 8 Projekte verwenden SPM standardmäßig), oder das CocoaPods-Pod des gleichen Namens, wenn Ihr Projekt CocoaPods noch verwendet, hinzu.
  • Android: auf android/app/build.gradle:
dependencies {
    implementation "com.google.android.ump:user-messaging-platform:<latest version>"
}

Verwenden Sie die neueste Version aus dem Maven-Repository von Google.

Erstellen ios/App/App/ConsentPlugin.swift:

import Capacitor
import UserMessagingPlatform

@objc(ConsentPlugin)
public class ConsentPlugin: CAPPlugin, CAPBridgedPlugin {
    public let identifier = "ConsentPlugin"
    public let jsName = "Consent"
    public let pluginMethods: [CAPPluginMethod] = [
        CAPPluginMethod(name: "gather", returnType: CAPPluginReturnPromise),
        CAPPluginMethod(name: "showPrivacyOptions", returnType: CAPPluginReturnPromise),
    ]

    @objc func gather(_ call: CAPPluginCall) {
        let parameters = RequestParameters()
        DispatchQueue.main.async {
            ConsentInformation.shared.requestConsentInfoUpdate(with: parameters) { error in
                if let error = error {
                    call.reject(error.localizedDescription)
                    return
                }
                guard let vc = self.bridge?.viewController else {
                    call.reject("No view controller")
                    return
                }
                ConsentForm.loadAndPresentIfRequired(from: vc) { formError in
                    if let formError = formError {
                        call.reject(formError.localizedDescription)
                        return
                    }
                    call.resolve(self.state())
                }
            }
        }
    }

    @objc func showPrivacyOptions(_ call: CAPPluginCall) {
        DispatchQueue.main.async {
            guard let vc = self.bridge?.viewController else {
                call.reject("No view controller")
                return
            }
            ConsentForm.presentPrivacyOptionsForm(from: vc) { formError in
                if let formError = formError {
                    call.reject(formError.localizedDescription)
                    return
                }
                call.resolve(self.state())
            }
        }
    }

    private func state() -> [String: Any] {
        return [
            "canRequestAds": ConsentInformation.shared.canRequestAds,
            "privacyOptionsRequired":
                ConsentInformation.shared.privacyOptionsRequirementStatus == .required,
        ]
    }
}

Registrieren Sie es von einem CAPBridgeViewController Unterklassen, und setzen Sie diese Klasse auf dem View-Controller in Main.storyboard:

import Capacitor

class MainViewController: CAPBridgeViewController {
    override open func capacitorDidLoad() {
        bridge?.registerPluginInstance(ConsentPlugin())
    }
}

Erstellen android/app/src/main/java/com/example/app/ConsentPlugin.java (Verwenden Sie Ihren Paketnamen):

package com.example.app;

import com.getcapacitor.JSObject;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.CapacitorPlugin;
import com.google.android.ump.ConsentInformation;
import com.google.android.ump.ConsentRequestParameters;
import com.google.android.ump.UserMessagingPlatform;

@CapacitorPlugin(name = "Consent")
public class ConsentPlugin extends Plugin {

    @PluginMethod
    public void gather(PluginCall call) {
        ConsentInformation info = UserMessagingPlatform.getConsentInformation(getContext());
        ConsentRequestParameters params = new ConsentRequestParameters.Builder().build();

        getActivity().runOnUiThread(() ->
            info.requestConsentInfoUpdate(
                getActivity(),
                params,
                () -> UserMessagingPlatform.loadAndShowConsentFormIfRequired(getActivity(), formError -> {
                    if (formError != null) {
                        call.reject(formError.getMessage());
                        return;
                    }
                    call.resolve(state(info));
                }),
                requestError -> call.reject(requestError.getMessage())
            )
        );
    }

    @PluginMethod
    public void showPrivacyOptions(PluginCall call) {
        getActivity().runOnUiThread(() ->
            UserMessagingPlatform.showPrivacyOptionsForm(getActivity(), formError -> {
                if (formError != null) {
                    call.reject(formError.getMessage());
                    return;
                }
                call.resolve(state(UserMessagingPlatform.getConsentInformation(getContext())));
            })
        );
    }

    private JSObject state(ConsentInformation info) {
        JSObject ret = new JSObject();
        ret.put("canRequestAds", info.canRequestAds());
        ret.put(
            "privacyOptionsRequired",
            info.getPrivacyOptionsRequirementStatus() ==
                ConsentInformation.PrivacyOptionsRequirementStatus.REQUIRED
        );
        return ret;
    }
}

Registrieren Sie es in MainActivity.java vorher super.onCreate:

public class MainActivity extends BridgeActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        registerPlugin(ConsentPlugin.class);
        super.onCreate(savedInstanceState);
    }
}

Rufen Sie es aus TypeScript auf

import { registerPlugin } from '@capacitor/core';
import { AdMob, BannerAd } from '@capgo/capacitor-admob';

interface ConsentState {
  canRequestAds: boolean;
  privacyOptionsRequired: boolean;
}

interface ConsentPlugin {
  gather(): Promise<ConsentState>;
  showPrivacyOptions(): Promise<ConsentState>;
}

const Consent = registerPlugin<ConsentPlugin>('Consent');

export async function startAds() {
  let state: ConsentState;
  try {
    state = await Consent.gather();
  } catch (err) {
    console.warn('Consent flow failed', err);
    return { showPrivacyEntry: false };
  }

  if (state.canRequestAds) {
    await AdMob.start();
    const banner = new BannerAd({
      adUnitId: 'ca-app-pub-3940256099942544/2934735716', // Google test banner (iOS)
      position: 'bottom',
    });
    await banner.show();
  }

  return { showPrivacyEntry: state.privacyOptionsRequired };
}

export const openPrivacyOptions = () => Consent.showPrivacyOptions();

Native code-Änderungen erfordern eine neue Build des Stores. Nachdem Sie das, können Sie die Zustimmungskopie auf Ihrer Einstellungsseite und die Werbeeinblendungslogik mitliefern Capgo Live-Updates.

Schritt 3: Fügen Sie die Datenschutzoptionen ein

When UMP reports that privacy options are required, Google expects a visible way to reopen the consent choices. Add a “Privacy settings” row to your settings page and hide it when not required:

const { showPrivacyEntry } = await startAds();
document.querySelector('#privacy-row')?.toggleAttribute('hidden', !showPrivacyEntry);
document.querySelector('#privacy-row')?.addEventListener('click', () => openPrivacyOptions());

wieder, bevor der nächste Werbeantrag erfolgt canRequestAds Schritt 4: App-Tracking-Transparenz auf iOS

Schritt 4: Transparenz bei der App-Tracking auf iOS

ATT is separate from GDPR. ATT controls access to the IDFA on iOS. GDPR consent controls whether and how personal data can be processed. You usually need both for an EU user on iOS.

  • zu NSUserTrackingUsageDescription to Info.plist.
  • Let UMP show the IDFA explainer message and trigger ATT, if you configured that message in AdMob. Otherwise, request ATT yourself after the consent flow.

With @capgo/capacitor-admob Sie können das ATT-Status direkt lesen und anfordern:

import { AdMob, TrackingAuthorizationStatus } from '@capgo/capacitor-admob';

const { status } = await AdMob.trackingAuthorizationStatus();
if (status === TrackingAuthorizationStatus.notDetermined) {
  await AdMob.requestTrackingAuthorization();
}

Capgo verfügt auch über einen separaten App Tracking Transparency-Plugin falls Sie ATT für andere SDKs benötigen. Vergessen Sie nicht, das Tracking in Ihrem Datenschutzmanifest und den App Store-Privatsphäre-Labels zu deklarieren, siehe unsere Anleitung zum Datenschutzmanifest.

Schritt 5: Testen mit Debug-Geographie

UMP zeigt das GDPR-Formular nur Benutzern in der EEA, UK oder der Schweiz. Um es anderswo zu testen:

  • Laufen Sie die App einmal aus und finden Sie die Protokollzeile von UMP mit Ihrem Geräte-Hashed-Id.
  • Laufen Sie das App einmal und finden Sie die Logzeile von UMP mit Ihrem Geräte-Hashed-Id. debugGeography and testDeviceIdentifiers und zu requestConsentInfo. In einer native Bridge setzen DebugSettings auf iOS und ConsentDebugSettings auf Android in Debug-Builds nur.
  • Zwischen den Starts resetten Sie das Einverständnis (resetConsentInfo() in der Community-Plugin, ConsentInformation.reset() nativ) so zeigt sich die Form wieder.

Schicken Sie niemals Debug-Einstellungen in Release-Builds. Gehen Sie sie auf einem Build-Flag ein.

Schritt 6: Fehler ohne Blockierung des Apps behandeln

Anfragen zum Einwilligung können fehlschlagen: kein Netzwerk, falsig konfigurierte App-ID oder keine veröffentlichte Nachricht. Fehlschlag als "keine Anzeigen für jetzt" behandeln, nicht als Crash.

  • Wenn requestConsentInfoUpdate fails but canRequestAds wahr war von einer vorherigen Sitzung, können Sie immer noch Anzeigen anfragen.
  • Wenn das Formular nicht geladen wird, logge es und versuche es auf dem nächsten Start erneut.
  • Zeige keine Anzeigen, solange das Einwilligungsfeld auf dem Bildschirm ist.

Fehlerbehebung

Das Formular zeigt sich nie. Die Nachricht wurde nicht veröffentlicht, nicht diesem App-ID zugewiesen oder Sie befinden sich außerhalb der EEA ohne Debug-Geographie. Überprüfen Sie die AdMob-App-ID in Info.plist und AndroidManifest.xml stimmt mit der Konsole überein.

Das Formular zeigt sich bei jedem Start. Der Benutzer schloss es ohne Wahl, oder Sie rufen in der Produktion code reset auf.

canRequestAds falsch für US-Benutzer. Sie veröffentlichten eine US-Bundesstaaten-Nachricht und der Benutzer entschied sich gegen den Verkauf oder die Weitergabe. Dienen Sie nur limitierte Anzeigen über den SDK, umgehen Sie es nicht.

Mediationspartner erhalten keine Einwilligung. Stellen Sie sicher, dass jeder Partneradapter aktuell ist und in der Liste Ihrer Datenschutzrichtlinie unter den Werbepartnern aufgeführt ist.

Die iOS ATT-Anzeige erscheint nie. NSUserTrackingUsageDescription Ist fehlend oder hat der Benutzer in den Einstellungen die Funktion "Zulassen, dass Apps nachverfolgen" deaktiviert.

Konsistenz über die Form hinaus

UMP übernimmt die Werbeseite. Ihre App benötigt jedoch immer noch eine Datenschutzerklärung, die AdMob, die Datenerhaltungsregeln und einen Weg zur Bearbeitung von Datenanfragen enthält. Unsere GDPR-Komplettliste umfasst den Rest der App.

Live-Updates für Capacitor-Apps

Wenn ein Web-Schicht-Bug live ist, liefern Sie die Reparatur über Capgo anstatt Tage für die Genehmigung im App-Store zu warten. Die Benutzer erhalten die Aktualisierung im Hintergrund, während native Änderungen im normalen Review-Prozess bleiben.

Unterstützung durch Menschen von Martin

Jetzt loslegen

Neueste Nachrichten aus unserem Blog

Capgo gibt Ihnen die besten Einblicke, die Sie benötigen, um ein wirklich professionelles mobiles App zu erstellen.