শুরু করুন

গুগল ইউজার মেসেজিং প্ল্যাটফর্ম (ইউএমপি) এসডিকে হলো একটি প্রাইভেসি ও মেসেজিং টুল যা আপনাকে গোপনীয়তার পছন্দগুলো পরিচালনা করতে সাহায্য করে। আরও তথ্যের জন্য, ‘গোপনীয়তা ও মেসেজিং সম্পর্কে’ দেখুন।

পূর্বশর্ত

  • অ্যান্ড্রয়েড এপিআই লেভেল ২১ বা তার বেশি (অ্যান্ড্রয়েডের জন্য)

একটি বার্তার ধরণ তৈরি করুন

আপনার AdMob অ্যাকাউন্টের 'গোপনীয়তা ও মেসেজিং' ট্যাবের অধীনে উপলব্ধ ব্যবহারকারী বার্তার প্রকারগুলির মধ্যে একটি ব্যবহার করে ব্যবহারকারীর বার্তা তৈরি করুন। UMP SDK আপনার প্রকল্পে সেট করা AdMob অ্যাপ্লিকেশন আইডি থেকে তৈরি একটি গোপনীয়তা বার্তা প্রদর্শন করার চেষ্টা করে।

আরও বিস্তারিত জানতে, গোপনীয়তা ও বার্তা আদানপ্রদান সম্পর্কে দেখুন।

SDK ইনস্টল করুন

  1. Firebase C++ SDK ইনস্টল করার জন্য ধাপগুলো অনুসরণ করুন। UMP C++ SDK, Firebase C++ SDK-এর অন্তর্ভুক্ত।

  2. এগিয়ে যাওয়ার আগে নিশ্চিত করুন যে আপনি প্রজেক্টে আপনার অ্যাপের AdMob অ্যাপ আইডি কনফিগার করেছেন

  3. আপনার কোডে, ConsentInfo::GetInstance() কল করে UMP SDK ইনিশিয়ালাইজ করুন।

    • অ্যান্ড্রয়েডে, আপনাকে NDK দ্বারা প্রদত্ত JNIEnv এবং Activity পাস করতে হবে। শুধুমাত্র প্রথমবার GetInstance() কল করার সময়ই আপনাকে এটি করতে হবে।
    • বিকল্পভাবে, যদি আপনি আপনার অ্যাপে আগে থেকেই Firebase C++ SDK ব্যবহার করে থাকেন, তাহলে প্রথমবার GetInstance() কল করার সময় একটি firebase::App পাস করতে পারেন।
    #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 ব্যবহার করা শেষ হলে, ConsentInfo ইনস্ট্যান্সটি ডিলিট করে আপনি SDK-টি বন্ধ করতে পারেন:

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

অ্যাসিঙ্ক্রোনাস অপারেশন নিরীক্ষণ করতে একটি Future ব্যবহার করুন

firebase::Future আপনাকে অ্যাসিঙ্ক্রোনাস মেথড কলগুলোর সমাপ্তির অবস্থা নির্ধারণ করার একটি উপায় প্রদান করে।

UMP-এর যে সকল C++ ফাংশন ও মেথড কল অ্যাসিঙ্ক্রোনাসভাবে কাজ করে, সেগুলো একটি Future রিটার্ন করে এবং সর্বশেষ অপারেশনের Future পাওয়ার জন্য একটি 'last result' ফাংশনও প্রদান করে।

Future থেকে ফলাফল পাওয়ার দুটি উপায় আছে:

  1. OnCompletion() কল করুন এবং এর সাথে আপনার নিজস্ব কলব্যাক ফাংশনটি পাস করুন, যেটি অপারেশনটি সম্পন্ন হলে কল করা হয়।
  2. নির্দিষ্ট সময় পর পর Future এর status() চেক করুন। যখন status-টি kFutureStatusPending থেকে kFutureStatusCompleted এ পরিবর্তিত হয়, তখন অপারেশনটি সম্পন্ন হয়ে যায়।

অ্যাসিঙ্ক্রোনাস অপারেশনটি সম্পন্ন হওয়ার পরে, অপারেশনটির এরর কোড পাওয়ার জন্য আপনার Future এর error() চেক করা উচিত। যদি এরর কোডটি 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.
          }
        });
      }
    });
}

কমপ্লিশন কলব্যাকের পরিবর্তে আপডেট লুপ পোলিং ব্যবহার করে কাজ সম্পন্ন হয়েছে কিনা তা পরীক্ষা করার একটি উদাহরণের জন্য উপরে দেখুন।

ব্যবহারকারী কোনো পছন্দ করার পর বা ফর্মটি বাতিল করার পর যদি কোনো কাজ করার প্রয়োজন হয়, তাহলে সেই লজিকটি LoadAndShowConsentFormIfRequired() থেকে ফেরত আসা Future হ্যান্ডেল করে এমন কোডের মধ্যে রাখুন।

গোপনীয়তার বিকল্পগুলি

কিছু গোপনীয়তা বার্তা ফর্ম একটি পাবলিশার-রেন্ডার করা গোপনীয়তা বিকল্প এন্ট্রি পয়েন্ট থেকে প্রদর্শিত হয়, যা ব্যবহারকারীদের যেকোনো সময় তাদের গোপনীয়তা বিকল্পগুলি পরিচালনা করতে দেয়। আপনার ব্যবহারকারীরা গোপনীয়তা বিকল্প এন্ট্রি পয়েন্টে কোন বার্তা দেখতে পান সে সম্পর্কে আরও জানতে, ‘উপলব্ধ ব্যবহারকারী বার্তার প্রকার’ দেখুন।

ব্যবহারকারীর সম্মতিতে বিজ্ঞাপনের অনুরোধ করুন

বিজ্ঞাপনের অনুরোধ করার আগে, ব্যবহারকারীর কাছ থেকে সম্মতি পেয়েছেন কিনা তা যাচাই করতে ConsentInfo::GetInstance()‑> CanRequestAds() ব্যবহার করুন:

সম্মতি সংগ্রহের সময় আপনি বিজ্ঞাপনের জন্য অনুরোধ করতে পারবেন কিনা, তা যাচাই করার জন্য নিম্নলিখিত স্থানগুলি তালিকাভুক্ত করা হলো:

  • বর্তমান সেশনে UMP SDK সম্মতি সংগ্রহ করার পর।
  • আপনি RequestConsentInfoUpdate() কল করার ঠিক পরেই। UMP SDK হয়তো আগের অ্যাপ সেশনেই সম্মতি পেয়ে গেছে।

সম্মতি সংগ্রহের প্রক্রিয়ার সময় কোনো ত্রুটি ঘটলে, আপনি বিজ্ঞাপনের জন্য অনুরোধ করতে পারেন কিনা তা পরীক্ষা করুন। UMP SDK পূর্ববর্তী অ্যাপ সেশনের সম্মতির স্থিতি ব্যবহার করে।

অপ্রয়োজনীয় বিজ্ঞাপন অনুরোধের কাজ প্রতিরোধ করুন

সম্মতি সংগ্রহের পর এবং RequestConsentInfoUpdate() কল করার পর, আপনি যখন ConsentInfo::GetInstance()‑> CanRequestAds() চেক করবেন, তখন নিশ্চিত করুন যে আপনার লজিকটি অপ্রয়োজনীয় বিজ্ঞাপনের অনুরোধ প্রতিরোধ করে, যার ফলে উভয় চেকই true রিটার্ন করতে পারে। উদাহরণস্বরূপ, একটি বুলিয়ান ভেরিয়েবল ব্যবহার করে এটি করা যেতে পারে।

নিম্নলিখিত সম্পূর্ণ উদাহরণটিতে আপডেট লুপ পোলিং ব্যবহার করা হয়েছে, কিন্তু আপনি অ্যাসিঙ্ক্রোনাস অপারেশন নিরীক্ষণের জন্য OnCompletion কলব্যাকও ব্যবহার করতে পারেন। যে পদ্ধতিটি আপনার কোডের কাঠামোর জন্য বেশি উপযুক্ত, সেটিই ব্যবহার করুন।

#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. লগ আউটপুটে নিম্নলিখিত উদাহরণের মতো একটি বার্তা খুঁজুন, যেখানে আপনার ডিভাইস আইডি এবং এটিকে একটি টেস্ট ডিভাইস হিসেবে কীভাবে যুক্ত করতে হবে তা দেখানো হয়েছে:

    অ্যান্ড্রয়েড

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

    আইওএস

    <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, debug_settings.debug_geography ব্যবহার করে আপনার অ্যাপের আচরণ পরীক্ষা করার একটি উপায় প্রদান করে, যেন ডিভাইসটি ইউরোপীয় অর্থনৈতিক অঞ্চল (EEA), যুক্তরাজ্য (UK) এবং সুইজারল্যান্ডের মতো বিভিন্ন অঞ্চলে অবস্থিত। উল্লেখ্য যে, ডিবাগ সেটিংস শুধুমাত্র পরীক্ষামূলক ডিভাইসেই কাজ করে।

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-তে Reset() মেথডটি রয়েছে।

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