Los gehts

Das Google User Messaging Platform (UMP) SDK ist ein Tool für Datenschutz und Mitteilungen, mit dem Sie Datenschutzeinstellungen verwalten können. Weitere Informationen finden Sie unter Datenschutz und Mitteilungen.

Vorbereitung

  • Android API-Level 21 oder höher (für Android)

Nachrichtentyp erstellen

Erstellen Sie Nutzermitteilungen mit einem der verfügbaren Nutzermitteilungstypen auf dem Tab Datenschutz und Mitteilungen Ihres AdMob-Kontos. Das UMP SDK versucht, eine Datenschutzmitteilung anzuzeigen, die aus der in Ihrem Projekt festgelegten AdMob-Anwendungs-ID erstellt wurde.

Weitere Informationen finden Sie unter Datenschutz und Mitteilungen.

SDK Installieren

  1. Folgen Sie der Anleitung zum Installieren des Firebase C++ SDK. Das UMP C++ SDK ist im Firebase C++ SDK enthalten.

  2. Achten Sie darauf, dass Sie die AdMob-App-ID Ihrer App im Projekt konfigurieren, bevor Sie fortfahren.

  3. Initialisieren Sie das UMP SDK in Ihrem Code, indem Sie ConsentInfo::GetInstance() aufrufen.

    • Unter Android müssen Sie die vom NDK bereitgestellten JNIEnv und Activity übergeben. Sie müssen dies nur beim ersten Aufruf von GetInstance() tun.
    • Wenn Sie das Firebase C++ SDK bereits in Ihrer App verwenden, können Sie alternativ beim ersten Aufruf von GetInstance() einen firebase::App übergeben.
    #include "firebase/ump/ump.h"
    
    namespace ump = ::firebase::ump;
    
    // Initialize using a firebase::App
    void InitializeUserMessagingPlatform(const firebase::App& app) {
      ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance(app);
    }
    
    // Initialize without a firebase::App
    #ifdef ANDROID
    void InitializeUserMessagingPlatform(JNIEnv* jni_env, jobject activity) {
      ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance(jni_env, activity);
    }
    #else  // non-Android
    void InitializeUserMessagingPlatform() {
      ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();
    }
    #endif
    

Nachfolgende Aufrufe von ConsentInfo::GetInstance() geben alle dieselbe Instanz zurück.

Wenn Sie das UMP SDK nicht mehr benötigen, können Sie es beenden, indem Sie die ConsentInfo-Instanz löschen:

void ShutdownUserMessagingPlatform() {
  ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();
  delete consent_info;
}

Future zum Überwachen asynchroner Vorgänge verwenden

Mit einem firebase::Future können Sie den Abschlussstatus asynchroner Methodenaufrufe ermitteln.

Alle UMP-C++-Funktionen und -Methodenaufrufe, die asynchron ausgeführt werden, geben ein Future zurück und stellen außerdem eine Funktion „Letztes Ergebnis“ bereit, mit der das Future des letzten Vorgangs abgerufen werden kann.

Es gibt zwei Möglichkeiten, ein Ergebnis von einem Future zu erhalten:

  1. Rufen Sie OnCompletion() auf und übergeben Sie Ihre eigene Callback-Funktion, die aufgerufen wird, wenn der Vorgang abgeschlossen ist.
  2. Prüfen Sie regelmäßig die status() des Future. Wenn sich der Status von kFutureStatusPending in kFutureStatusCompleted ändert, ist der Vorgang abgeschlossen.

Nach Abschluss des asynchronen Vorgangs sollten Sie den error() des Future prüfen, um den Fehlercode des Vorgangs zu erhalten. Wenn der Fehlercode 0 (kConsentRequestSuccess oder kConsentFormSuccess) lautet, wurde der Vorgang erfolgreich abgeschlossen. Prüfen Sie andernfalls den Fehlercode und die error_message(), um festzustellen, was schiefgelaufen ist.

Abschluss-Callback

Hier ist ein Beispiel dafür, wie Sie mit OnCompletion einen Abschluss-Callback festlegen, der aufgerufen wird, wenn der asynchrone Vorgang abgeschlossen ist.

void MyApplicationStart() {
  // [... other app initialization code ...]

  ump::ConsentInfo *consent_info = ump::ConsentInfo::GetInstance();

  // See the section below for more information about RequestConsentInfoUpdate.
  firebase::Future<void> result = consent_info->RequestConsentInfoUpdate(...);

  result.OnCompletion([](const firebase::Future<void>& req_result) {
    if (req_result.error() == ump::kConsentRequestSuccess) {
      // Operation succeeded. You can now call LoadAndShowConsentFormIfRequired().
    } else {
      // Operation failed. Check req_result.error_message() for more information.
    }
  });
}

Aktualisierungsschleifen-Abfrage

In diesem Beispiel wird beim Start der App ein asynchroner Vorgang gestartet. Die Ergebnisse werden dann an anderer Stelle in der Update-Schleifenfunktion des Spiels geprüft, die einmal pro Frame ausgeführt wird.

ump::ConsentInfo *g_consent_info = nullptr;
bool g_waiting_for_request = false;

void MyApplicationStart() {
  // [... other app initialization code ...]

  g_consent_info = ump::ConsentInfo::GetInstance();
  // See the section below for more information about RequestConsentInfoUpdate.
  g_consent_info->RequestConsentInfoUpdate(...);
  g_waiting_for_request = true;
}

// Elsewhere, in the game's update loop, which runs once per frame:
void MyGameUpdateLoop() {
  // [... other game logic here ...]

  if (g_waiting_for_request) {
    // Check whether RequestConsentInfoUpdate() has finished.
    // Calling "LastResult" returns the Future for the most recent operation.
    firebase::Future<void> result =
      g_consent_info->RequestConsentInfoUpdateLastResult();

    if (result.status() == firebase::kFutureStatusComplete) {
      g_waiting_for_request = false;
      if (result.error() == ump::kConsentRequestSuccess) {
        // Operation succeeded. You can call LoadAndShowConsentFormIfRequired().
      } else {
        // Operation failed. Check result.error_message() for more information.
      }
    }
  }
}

Weitere Informationen zu firebase::Future finden Sie in der Dokumentation zum Firebase C++ SDK und in der Dokumentation zum GMA C++ SDK.

Sie sollten bei jedem App-Start mit RequestConsentInfoUpdate() eine Aktualisierung der Einwilligungsinformationen des Nutzers anfordern. Mit dieser Anfrage wird Folgendes geprüft:

  • Ob eine Einwilligung erforderlich ist. Beispielsweise ist die Einwilligung zum ersten Mal erforderlich oder die vorherige Einwilligungsentscheidung ist abgelaufen.
  • Ob ein Einstiegspunkt für Datenschutzoptionen erforderlich ist. Bei einigen Datenschutzmitteilungen müssen Nutzer in Apps jederzeit die Möglichkeit haben, ihre Datenschutzeinstellungen zu ändern.
#include "firebase/ump/ump.h"

namespace ump = ::firebase::ump;

void MyApplicationStart(ump::FormParent parent) {
  ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();

  // Create a ConsentRequestParameters struct..
  ump::ConsentRequestParameters params;
  // Set tag for under age of consent. False means users are NOT under age of consent.
  params.tag_for_under_age_of_consent = false;

  consent_info->RequestConsentInfoUpdate(params).OnCompletion(
    [*](const Future<void>& req_result) {
      if (req_result.error() != ump::kConsentRequestSuccess) {
        // req_result.error() is a kConsentRequestError enum.
        LogMessage("Error requesting consent update: %s", req_result.error_message());
      }
      // Consent information is successfully updated.
    });
}

Formular für Datenschutzmitteilungen laden und präsentieren

Nachdem Sie den aktuellen Einwilligungsstatus erhalten haben, rufen Sie LoadAndShowConsentFormIfRequired() auf, um alle Formulare zu laden, die zum Einholen der Nutzereinwilligung erforderlich sind. Nach dem Laden werden die Formulare sofort angezeigt.

#include "firebase/ump/ump.h"

namespace ump = ::firebase::ump;

void MyApplicationStart(ump::FormParent parent) {
  ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();

  // Create a ConsentRequestParameters struct..
  ump::ConsentRequestParameters params;
  // Set tag for under age of consent. False means users are NOT under age of consent.
  params.tag_for_under_age_of_consent = false;

  consent_info->RequestConsentInfoUpdate(params).OnCompletion(
    [*](const Future<void>& req_result) {
      if (req_result.error() != ump::kConsentRequestSuccess) {
        // req_result.error() is a kConsentRequestError enum.
        LogMessage("Error requesting consent update: %s", req_result.error_message());
      } else {
        consent_info->LoadAndShowConsentFormIfRequired(parent).OnCompletion(
        [*](const Future<void>& form_result) {
          if (form_result.error() != ump::kConsentFormSuccess) {
            // form_result.error() is a kConsentFormError enum.
            LogMessage("Error showing privacy message form: %s", form_result.error_message());
          } else {
            // Either the form was shown and completed by the user, or consent was not required.
          }
        });
      }
    });
}

Oben finden Sie ein Beispiel für die Prüfung auf Abschluss mithilfe von Update-Loop-Polling anstelle eines Abschluss-Callbacks.

Wenn Sie nach der Auswahl oder dem Schließen des Formulars durch den Nutzer weitere Aktionen ausführen möchten, platzieren Sie diese Logik in dem Code, der den von LoadAndShowConsentFormIfRequired() zurückgegebenen Future verarbeitet.

Datenschutzoptionen

Einige Formen von Datenschutzmitteilungen werden über einen vom Publisher gerenderten Einstiegspunkt für Datenschutzoptionen angezeigt, sodass Nutzer ihre Datenschutzoptionen jederzeit verwalten können. Weitere Informationen dazu, welche Mitteilung Ihre Nutzer am Einstiegspunkt für Datenschutzoptionen sehen, finden Sie unter Verfügbare Arten von Nutzermitteilungen.

Anzeigen mit Nutzereinwilligung anfordern

Bevor Sie Anzeigen anfordern, prüfen Sie mit ConsentInfo::GetInstance()‑> CanRequestAds(), ob Sie die Einwilligung des Nutzers eingeholt haben:

An den folgenden Stellen können Sie prüfen, ob Sie Anzeigen anfordern können, während Sie die Einwilligung einholen:

  • Nachdem das UMP SDK in der aktuellen Sitzung die Einwilligung eingeholt hat.
  • Unmittelbar nach dem Aufruf von RequestConsentInfoUpdate(). Das UMP SDK hat möglicherweise in der vorherigen App-Sitzung die Einwilligung eingeholt.

Wenn während der Einwilligungserhebung ein Fehler auftritt, prüfen Sie, ob Sie Anzeigen anfordern können. Das UMP SDK verwendet den Einwilligungsstatus aus der vorherigen App-Sitzung.

Redundante Anzeigenanfragen vermeiden

Wenn Sie ConsentInfo::GetInstance()‑> CanRequestAds() nach dem Einholen der Einwilligung und nach dem Aufrufen von RequestConsentInfoUpdate() prüfen, sollten Sie darauf achten, dass Ihre Logik redundante Anzeigenanfragen verhindert, die dazu führen könnten, dass beide Prüfungen true zurückgeben. Beispiel: mit einer booleschen Variable.

Im folgenden vollständigen Beispiel wird die Aktualisierungsschleife abgefragt. Sie können aber auch OnCompletion-Callbacks verwenden, um asynchrone Vorgänge zu überwachen. Verwenden Sie die Technik, die am besten zu Ihrer Codestruktur passt.

#include "firebase/future.h"
#include "firebase/gma/gma.h"
#include "firebase/ump/ump.h"

namespace gma = ::firebase::gma;
namespace ump = ::firebase::ump;
using firebase::Future;

ump::ConsentInfo* g_consent_info = nullptr;
// State variable for tracking the UMP consent flow.
enum { kStart, kRequest, kLoadAndShow, kInitGma, kFinished, kErrorState } g_state = kStart;
bool g_ads_allowed = false;

void MyApplicationStart() {
  g_consent_info = ump::ConsentInfo::GetInstance(...);

  // Create a ConsentRequestParameters struct..
  ump::ConsentRequestParameters params;
  // Set tag for under age of consent. False means users are NOT under age of consent.
  params.tag_for_under_age_of_consent = false;

  g_consent_info->RequestConsentInfoUpdate(params);
  // CanRequestAds() can return a cached value from a previous run immediately.
  g_ads_allowed = g_consent_info->CanRequestAds();
  g_state = kRequest;
}

// This function runs once per frame.
void MyGameUpdateLoop() {
  // [... other game logic here ...]

  if (g_state == kRequest) {
    Future<void> req_result = g_consent_info->RequestConsentInfoUpdateLastResult();

    if (req_result.status() == firebase::kFutureStatusComplete) {
      g_ads_allowed = g_consent_info->CanRequestAds();
      if (req_result.error() == ump::kConsentRequestSuccess) {
        // You must provide the FormParent (Android Activity or iOS UIViewController).
        ump::FormParent parent = GetMyFormParent();
        g_consent_info->LoadAndShowConsentFormIfRequired(parent);
        g_state = kLoadAndShow;
      } else {
        LogMessage("Error requesting consent status: %s", req_result.error_message());
        g_state = kErrorState;
      }
    }
  }
  if (g_state == kLoadAndShow) {
    Future<void> form_result = g_consent_info->LoadAndShowConsentFormIfRequiredLastResult();

    if (form_result.status() == firebase::kFutureStatusComplete) {
      g_ads_allowed = g_consent_info->CanRequestAds();
      if (form_result.error() == ump::kConsentRequestSuccess) {
        if (g_ads_allowed) {
          // Initialize GMA. This is another asynchronous operation.
          firebase::gma::Initialize();
          g_state = kInitGma;
        } else {
          g_state = kFinished;
        }
        // Optional: shut down the UMP SDK to save memory.
        delete g_consent_info;
        g_consent_info = nullptr;
      } else {
        LogMessage("Error displaying privacy message form: %s", form_result.error_message());
        g_state = kErrorState;
      }
    }
  }
  if (g_state == kInitGma && g_ads_allowed) {
    Future<gma::AdapterInitializationStatus> gma_future = gma::InitializeLastResult();

    if (gma_future.status() == firebase::kFutureStatusComplete) {
      if (gma_future.error() == gma::kAdErrorCodeNone) {
        g_state = kFinished;
        // TODO: Request an ad.
      } else {
        LogMessage("Error initializing GMA: %s", gma_future.error_message());
        g_state = kErrorState;
      }
    }
  }
}

Test

Wenn Sie die Integration in Ihrer App während der Entwicklung testen möchten, gehen Sie so vor, um Ihr Testgerät programmatisch zu registrieren. Entfernen Sie den Code, mit dem diese Testgeräte-IDs festgelegt werden, bevor Sie Ihre App veröffentlichen.

  1. Rufen Sie einfach RequestConsentInfoUpdate() an.
  2. Suchen Sie in der Logausgabe nach einer Meldung, die in etwa so aussieht wie im folgenden Beispiel. Sie enthält Ihre Geräte-ID und eine Anleitung, wie Sie sie als Testgerät hinzufügen:

    Android

    Use new ConsentDebugSettings.Builder().addTestDeviceHashedId("33BE2250B43518CCDA7DE426D04EE231")
    to set this as a debug device.
    

    iOS

    <UMP SDK>To enable debug mode for this device,
    set: UMPDebugSettings.testDeviceIdentifiers = @[2077ef9a63d2b398840261c8221a0c9b]
    
  3. Kopieren Sie die Geräte-ID Ihres Testgeräts in die Zwischenablage.

  4. Ändern Sie Ihren Code so, dass ConsentRequestParameters.debug_settings.debug_device_ids auf eine Liste Ihrer Testgeräte-IDs festgelegt wird.

    void MyApplicationStart() {
      ump::ConsentInfo consent_info = ump::ConsentInfo::GetInstance(...);
    
      ump::ConsentRequestParameters params;
      params.tag_for_under_age_of_consent = false;
      params.debug_settings.debug_device_ids = {"TEST-DEVICE-HASHED-ID"};
    
      consent_info->RequestConsentInfoUpdate(params);
    }
    

Geografie erzwingen

Mit dem UMP SDK können Sie das Verhalten Ihrer App so testen, als ob sich das Gerät in verschiedenen Regionen wie dem Europäischen Wirtschaftsraum (EWR), dem Vereinigten Königreich und der Schweiz befinden würde. Verwenden Sie dazu debug_settings.debug_geography. Beachten Sie, dass die Debug-Einstellungen nur auf Testgeräten funktionieren.

void MyApplicationStart() {
  ump::ConsentInfo consent_info = ump::ConsentInfo::GetInstance(...);

  ump::ConsentRequestParameters params;
  params.tag_for_under_age_of_consent = false;
  params.debug_settings.debug_device_ids = {"TEST-DEVICE-HASHED-ID"};
  // Geography appears as EEA for debug devices.
  params.debug_settings.debug_geography = ump::kConsentDebugGeographyEEA

  consent_info->RequestConsentInfoUpdate(params);
}

Wenn Sie Ihre App mit dem UMP SDK testen, kann es hilfreich sein, den Status des SDK zurückzusetzen, um die erste Installation durch einen Nutzer zu simulieren. Das SDK bietet hierfür die Methode Reset().

  ConsentInfo::GetInstance()->Reset();