מתחילים

‫Google User Messaging Platform (UMP) SDK הוא כלי לניהול פרטיות והודעות שיעזור לכם לנהל את העדפות הפרטיות של המשתמשים. מידע נוסף זמין במאמר בנושא הכלי 'פרטיות והודעות'.

דרישות מוקדמות

  • רמת API‏ 21 ומעלה ב-Android (ל-Android)

יצירת סוג הודעה

יוצרים הודעות למשתמשים באמצעות אחד מהסוגים הזמינים של הודעות למשתמשים בכרטיסייה פרטיות והודעות בחשבון AdMob. ‫UMP SDK מנסה להציג הודעה בנושא פרטיות שנוצרה ממזהה האפליקציה ב-AdMob שהוגדר בפרויקט.

פרטים נוספים מופיעים במאמר בנושא פרטיות והודעות.

התקנת ה-SDK

  1. פועלים לפי השלבים להתקנת Firebase C++ SDK. ה-SDK של UMP C++‎ כלול ב-Firebase C++ SDK.

  2. לפני שממשיכים, חשוב לוודא שמזהה האפליקציה ב-AdMob מוגדר בפרויקט.

  3. בקוד, מפעילים את UMP SDK על ידי קריאה ל-ConsentInfo::GetInstance().

    • ב-Android, צריך להעביר את הערכים JNIEnv ו-Activity שסופקו על ידי NDK. צריך לעשות את זה רק בפעם הראשונה שמתקשרים אל GetInstance().
    • לחלופין, אם אתם כבר משתמשים ב-Firebase C++ SDK באפליקציה, אתם יכולים להעביר firebase::App בפעם הראשונה שאתם קוראים ל-GetInstance().
    #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
    

שיחות עוקבות אל ConsentInfo::GetInstance() מחזירות את אותו מופע.

אם סיימתם להשתמש ב-UMP SDK, אתם יכולים להשבית את ה-SDK על ידי מחיקת המופע ConsentInfo:

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

שימוש ב-Future כדי לעקוב אחרי פעולות אסינכרוניות

‫A firebase::Future מספק דרך לקבוע את סטטוס ההשלמה של קריאות לשיטות אסינכרוניות.

כל הפונקציות והפעלות ה-method של UMP C++ שפועלות באופן אסינכרוני מחזירות Future, ומספקות גם פונקציה של "התוצאה האחרונה" כדי לאחזר את Future מהפעולה האחרונה.

יש שתי דרכים לקבל תוצאה מ-Future:

  1. קוראים ל-OnCompletion() ומעבירים את פונקציית הקריאה החוזרת שלכם, שהמערכת קוראת לה כשהפעולה מסתיימת.
  2. כדאי לבדוק מדי פעם את Futurestatus(). כשהערך של status משתנה מ-kFutureStatusPending ל-kFutureStatusCompleted, הפעולה הושלמה.

אחרי שהפעולה האסינכרונית מסתיימת, צריך לבדוק את Futureerror() כדי לקבל את קוד השגיאה של הפעולה. אם קוד השגיאה הוא 0 (kConsentRequestSuccess או kConsentFormSuccess), הפעולה הושלמה בהצלחה. אחרת, צריך לבדוק את קוד השגיאה ואת error_message() כדי להבין מה השתבש.

התקשרות חזרה להשלמה

בדוגמה הבאה אפשר לראות איך משתמשים ב-OnCompletion כדי להגדיר קריאה חוזרת להשלמה, שמופעלת כשהפעולה האסינכרונית מסתיימת.

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.
    }
  });
}

עדכון של סקרים חוזרים

בדוגמה הזו, אחרי הפעלה של פעולה אסינכרונית בהפעלת האפליקציה, התוצאות נבדקות במקום אחר, בפונקציית לולאת העדכון של המשחק (שמופעלת פעם אחת לכל פריים).

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.
      }
    }
  }
}

מידע נוסף על firebase::Future זמין במסמכי התיעוד של Firebase C++ SDK ובמסמכי התיעוד של GMA C++ SDK.

צריך לבקש עדכון של פרטי ההסכמה של המשתמש בכל הפעלה של האפליקציה באמצעות RequestConsentInfoUpdate(). הבקשה הזו בודקת את הדברים הבאים:

  • האם נדרשת הסכמה. לדוגמה, נדרשת הסכמה בפעם הראשונה, או שההחלטה הקודמת לגבי הסכמה פגה.
  • האם נדרשת נקודת כניסה לאפשרויות הפרטיות. חלק מההודעות בנושא פרטיות מחייבות את האפליקציות לאפשר למשתמשים לשנות את אפשרויות הפרטיות שלהם בכל שלב.
#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.
    });
}

טעינה והצגה של טופס הודעת הפרטיות

אחרי שמתקבל מצב ההסכמה העדכני ביותר, צריך להתקשר אל LoadAndShowConsentFormIfRequired() כדי לטעון את הטפסים שנדרשים לאיסוף הסכמה מהמשתמשים. אחרי הטעינה, הטפסים מוצגים מיד.

#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.
          }
        });
      }
    });
}

בדוגמה למעלה אפשר לראות איך בודקים אם הפעולה הושלמה באמצעות דגימת לולאת עדכון במקום קריאה חוזרת להשלמה.

אם אתם צריכים לבצע פעולות כלשהן אחרי שהמשתמש בחר אפשרות או סגר את הטופס, אתם צריכים להציב את הלוגיקה הזו בקוד שמטפל בערך Future שמוחזר על ידי LoadAndShowConsentFormIfRequired().

אפשרויות פרטיות

חלק מהטפסים של ההודעות בנושא פרטיות מוצגים מנקודת כניסה לאפשרויות הפרטיות שמוצגת על ידי בעל התוכן הדיגיטלי, ומאפשרים למשתמשים לנהל את אפשרויות הפרטיות שלהם בכל שלב. מידע נוסף על ההודעה שתוצג למשתמשים בנקודת הכניסה לאפשרויות הפרטיות זמין במאמר הסוגים הזמינים של הודעות למשתמשים.

בקשת מודעות עם הסכמת משתמשים

לפני ששולחים בקשות להצגת מודעות, משתמשים ב- ConsentInfo::GetInstance()‑> CanRequestAds() כדי לבדוק אם קיבלתם הסכמה מהמשתמש:

אלה המקומות שבהם אפשר לבדוק אם אפשר לבקש הצגת מודעות בזמן איסוף הסכמה:

  • אחרי ש-UMP SDK אוסף הסכמה בסשן הנוכחי.
  • מיד אחרי שמתקשרים אל RequestConsentInfoUpdate(). יכול להיות ש-UMP SDK קיבל הסכמה בסשן הקודם באפליקציה.

אם מתרחשת שגיאה במהלך תהליך איסוף ההסכמה, צריך לבדוק אם אפשר לשלוח בקשות להצגת מודעות. ‫UMP SDK משתמש בסטטוס ההסכמה מהסשן הקודם באפליקציה.

בדוגמה המלאה הבאה נעשה שימוש בדגימה של לולאת עדכון, אבל אפשר גם להשתמש ב-OnCompletioncallbacks כדי לעקוב אחרי פעולות אסינכרוניות. משתמשים בטכניקה שמתאימה יותר למבנה הקוד.

#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;
      }
    }
  }
}

בדיקה

אם אתם רוצים לבדוק את השילוב באפליקציה במהלך הפיתוח, אתם יכולים לבצע את השלבים הבאים כדי לרשום את מכשיר הבדיקה באופן אוטומטי. חשוב להסיר את הקוד שמגדיר את מזהי מכשירי הבדיקה האלה לפני שמשחררים את האפליקציה.

  1. התקשרו אל RequestConsentInfoUpdate().
  2. בודקים את פלט היומן ומחפשים הודעה שדומה לדוגמה הבאה, שבה מוצג מזהה המכשיר והסבר איך להוסיף אותו כמכשיר בדיקה:

    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. מעתיקים את מזהה מכשיר הבדיקה ללוח.

  4. משנים את הקוד כדי להגדיר את ConsentRequestParameters.debug_settings.debug_device_ids לרשימה של מזהי מכשירי הבדיקה.

    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);
    }
    

אילוץ של מיקום גיאוגרפי

באמצעות UMP SDK אפשר לבדוק את אופן הפעולה של האפליקציה במקרה שבו המכשיר נמצא באזורים שונים, כמו EEA או בריטניה, באמצעות debug_settings.debug_geography. הערה: הגדרות ניפוי הבאגים פועלות רק במכשירי בדיקה.

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);
}

כשבודקים את האפליקציה באמצעות ה-UMP SDK, יכול להיות שיהיה שימושי לאפס את מצב ה-SDK כדי לדמות את חוויית ההתקנה הראשונית של המשתמש. ה-SDK מספק את ה-method‏ Reset() כדי לעשות את זה.

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