ตรวจสอบสิทธิ์โดยใช้บริการเกม Google Play ด้วย C++

คุณสามารถใช้บริการ Google Play Games เพื่อลงชื่อเข้าใช้ผู้เล่นในเกม Android ที่สร้างบน Firebase และเขียนด้วยภาษา C++ ในการใช้บริการ Google Play Games ลงชื่อเข้าใช้ด้วย Firebase ก่อนอื่นให้ลงชื่อเข้าใช้โปรแกรมเล่นด้วย Google Play Games และขอรหัสตรวจสอบสิทธิ์ OAuth 2.0 เมื่อคุณดำเนินการดังกล่าว จากนั้นผ่านรหัสรับรองความถูกต้องในการ PlayGamesAuthProvider เพื่อสร้างการรับรอง Firebase ซึ่งคุณสามารถใช้เพื่อตรวจสอบกับ Firebase

ก่อนจะเริ่ม

ก่อนที่คุณจะสามารถใช้ การตรวจสอบสิทธิ์ Firebase คุณจะต้อง:

  • ลงทะเบียนโปรเจ็กต์ C++ ของคุณและกำหนดค่าให้ใช้ Firebase

    หากโปรเจ็กต์ C++ ของคุณใช้ Firebase อยู่แล้ว แสดงว่าได้ลงทะเบียนและกำหนดค่าสำหรับ Firebase แล้ว

  • เพิ่ม Firebase c ++ SDK กับโครงการของคุณ C ++

หมายเหตุว่าการเพิ่ม Firebase กับ C ++ ของโครงการที่เกี่ยวข้องกับงานทั้งใน Firebase คอนโซล และเปิดโครงการ c ++ ของคุณ (เช่นคุณดาวน์โหลดไฟล์การกำหนดค่า Firebase จากคอนโซลแล้วย้ายพวกเขาเข้าไปใน ++ โครงการ C ของคุณ)

ตั้งค่าโปรเจ็กต์ Firebase

  1. หากคุณยังไม่ได้ตั้งเกมของคุณ SHA-1 ลายนิ้วมือใน การตั้งค่า หน้าของคอนโซล Firebase

    คุณจะได้รับกัญชา SHA ใบรับรองการลงนามของคุณด้วย gradle signingReport สั่ง:

    ./gradlew signingReport

  2. เปิดใช้งาน Google Play Games เป็นผู้ให้บริการลงชื่อเข้าใช้:

    1. ค้นหารหัสไคลเอ็นต์เว็บเซิร์ฟเวอร์ของโปรเจ็กต์และข้อมูลลับไคลเอ็นต์ รหัสไคลเอ็นต์ของเว็บเซิร์ฟเวอร์ระบุโปรเจ็กต์ Firebase ของคุณไปยังเซิร์ฟเวอร์การตรวจสอบสิทธิ์ของ Google Play

      หากต้องการค้นหาค่าเหล่านี้:

      1. เปิดโครงการ Firebase ของคุณใน Google APIs คอนโซล ข้อมูลประจำตัวหน้า
      2. ใน OAuth 2.0 รหัสลูกค้าส่วนเปิดเว็บไคลเอ็นต์ (รถยนต์ที่สร้างขึ้นโดยการให้บริการ Google) รายละเอียดหน้า หน้านี้แสดงรายการ ID และข้อมูลลับของไคลเอ็นต์เว็บเซิร์ฟเวอร์ของคุณ
    2. จากนั้นใน คอนโซล Firebase เปิดการตรวจสอบสิทธิ์

    3. ที่ลงในแท็บวิธีการเปิดใช้งานการเล่นเกมส์การลงชื่อเข้าใช้ผู้ให้บริการ คุณจะต้องระบุรหัสไคลเอ็นต์เว็บเซิร์ฟเวอร์ของโปรเจ็กต์และข้อมูลลับของไคลเอ็นต์ซึ่งได้รับจากคอนโซล API

  1. ใน คอนโซล Google Play เปิดแอปของคุณหรือสร้างหนึ่ง

  2. ในส่วนเติบโตคลิก Play บริการเกม> การตั้งค่าและการจัดการ> การกำหนดค่า

  3. คลิกใช่เกมของฉันแล้วใช้ Google APIs เลือกชื่อของโครงการ Firebase ของคุณจากรายการและคลิกใช้

  4. ในการเล่นเกมส์บริการหน้าการกำหนดค่าคลิกเพิ่มข้อมูลประจำตัว

    1. เลือกเกมชนิดของเซิร์ฟเวอร์
    2. ในด้านลูกค้า OAuth เลือกรหัสลูกค้าเว็บโครงการของคุณ ตรวจสอบว่ารหัสนี้เป็นรหัสไคลเอ็นต์เดียวกับที่คุณระบุเมื่อเปิดใช้การลงชื่อเข้าใช้ Play Games
    3. บันทึกการเปลี่ยนแปลงของคุณ
  5. ยังคงอยู่ในการเล่นเกมส์บริการหน้าการกำหนดค่าคลิกเพิ่มข้อมูลประจำตัวอีกครั้ง

    1. เลือกประเภทของ Android
    2. ในด้านลูกค้า OAuth เลือก Android รหัสลูกค้าของโครงการ (หากคุณไม่เห็นรหัสไคลเอ็นต์ Android ของคุณ ตรวจสอบให้แน่ใจว่าคุณได้ตั้งค่าลายนิ้วมือ SHA-1 ของเกมในคอนโซล Firebase)
    3. บันทึกการเปลี่ยนแปลงของคุณ
  6. ในหน้าทดสอบเพิ่มที่อยู่อีเมลของผู้ใช้ที่ต้องการเพื่อให้สามารถเข้าสู่ระบบในเกมของคุณก่อนที่คุณจะปล่อยมันบน Play สโตร์

รวมการลงชื่อเข้าใช้ Play Games เข้ากับเกมของคุณ

ก่อนที่คุณจะสามารถลงชื่อเข้าใช้ผู้เล่นในเกมของคุณ คุณต้องรวมการลงชื่อเข้าใช้ Google Play Games

วิธีที่ง่ายที่สุดและแนะนำเพื่อเพิ่มการสนับสนุนสำหรับการเล่นเกมในการลงชื่อเข้าโครงการ C ++ Android คือการใช้ Google เข้าสู่ระบบใน C ++ SDK

หากต้องการเพิ่มการลงชื่อเข้าใช้ Play Games ให้กับเกมของคุณโดยใช้ Google Sign-in C++ SDK ให้ทำดังต่อไปนี้:

  1. โคลนหรือดาวน์โหลด เข้าสู่ระบบในพื้นที่เก็บข้อมูลความสามัคคีปลั๊กอิน Google ซึ่งยังมี c ++ SDK

  2. สร้างโครงการที่มีอยู่ใน staging/native/ ไดเรกทอรีทั้งการใช้สตูดิโอ Android หรือ gradlew build

    สร้างสำเนาการส่งออกไปยังไดเรกทอรีชื่อ google-signin-cpp

  3. รวม Google Sign-in C++ SDK ในไฟล์สร้างโค้ดเนทีฟของเกมของคุณ:

    CMake

    ในระดับบนสุดของคุณ CMakeLists.txt ไฟล์:

    set(GSI_PACKAGE_DIR "/path/to/google-signin-cpp")
    add_library(lib-google-signin-cpp STATIC IMPORTED) set_target_properties(lib-google-signin-cpp PROPERTIES IMPORTED_LOCATION     ${GSI_PACKAGE_DIR}/lib/${ANDROID_ABI}/libgoogle-signin-cpp.a )
    ...
    target_link_libraries(     ...     lib-google-signin-cpp)

    ndk-build

    ในของคุณ Android.mk ไฟล์:

    include $(CLEAR_VARS)
    LOCAL_MODULE := google-signin-cpp
    GSI_SDK_DIR := /path/to/google-signin-cpp
    LOCAL_SRC_FILES := $(GSI_SDK_DIR)/lib/$(TARGET_ARCH_ABI)/libgoogle-signin-cpp.a
    LOCAL_EXPORT_C_INCLUDES := $(GSI_SDK_DIR)/include
    include $(PREBUILT_STATIC_LIBRARY)
    

  4. ถัดไป รวมคอมโพเนนต์ตัวช่วย Java ซึ่ง C++ SDK ต้องการ

    จะทำเช่นนั้นในระดับโครงการของคุณ build.gradle ไฟล์เพิ่มไดเรกทอรีออก SDK สร้างเป็นพื้นที่เก็บข้อมูลท้องถิ่น:

    allprojects {
        repositories {
            // ...
            flatDir {
                dirs 'path/to/google-signin-cpp'
            }
        }
    }
    

    และในระดับโมดูลของคุณ build.gradle ไฟล์ประกาศองค์ประกอบผู้ช่วยที่เป็นพึ่งพา:

    dependencies {
        implementation 'com.google.android.gms:play-services-auth:20.0.1'
        // Depend on the AAR built with the Google Sign-in SDK in order to add
        // the Java helper classes, which are used by the C++ library.
        compile(name:'google-signin-cpp-release', ext:'aar')
    }
    
  5. จากนั้นในเกมของคุณให้กำหนดค่า GoogleSignIn วัตถุเพื่อใช้เล่นเกมส์การลงชื่อเข้าใช้และเรียกรหัสเซิร์ฟเวอร์รับรองความถูกต้องดังนี้

    #include "google_signin.h"
    #include "future.h"
    
    using namespace google::signin;
    
    // ...
    
    GoogleSignIn::Configuration config = {};
    config.web_client_id = "YOUR_WEB_CLIENT_ID_HERE";
    config.request_id_token = false;
    config.use_game_signin = true;
    config.request_auth_code = true;
    
    GoogleSignIn gsi = GoogleSignIn(GetActivity(), GetJavaVM());
    gsi.Configure(config);
    
  6. สุดท้ายโทร SignIn() เพื่อเข้าสู่ระบบของผู้เล่นในการเล่นเกมนี้:

    Future<GoogleSignIn::SignInResult> &future = gsi.SignIn();
    

    เมื่ออนาคตกลับโดย SignIn() แก้ไขคุณจะได้รับรหัสเซิร์ฟเวอร์รับรองความถูกต้องจากผลที่ได้:

    if (!future.Pending()) {
        const GoogleSignIn::StatusCode status =
                static_cast<GoogleSignIn::StatusCode>(future.Status());
        if (status == GoogleSignIn::kStatusCodeSuccess) {
            // Player successfully signed in to Google Play! Get auth code to
            //   pass to Firebase
            const GoogleSignIn::SignInResult result =
                    static_cast<GoogleSignIn::SignInResult>(future.Result());
            const char* server_auth_code = result.User.GetServerAuthCode();
        }
    }
    

ตรวจสอบสิทธิ์ด้วย Firebase

หลังจากที่ผู้เล่นลงชื่อเข้าใช้ Play Games แล้ว คุณจะใช้รหัสตรวจสอบสิทธิ์เพื่อตรวจสอบสิทธิ์กับ Firebase ได้

  1. หลังจากที่ผู้เล่นลงชื่อเข้าใช้ Play Games สำเร็จแล้ว ให้รับรหัสตรวจสอบสิทธิ์สำหรับบัญชีของผู้เล่น

  2. จากนั้น แลกเปลี่ยนรหัสการตรวจสอบสิทธิ์จากบริการ Play Games สำหรับข้อมูลรับรอง Firebase และใช้ข้อมูลรับรอง Firebase เพื่อตรวจสอบสิทธิ์ผู้เล่น:

    firebase::auth::Credential credential =
        firebase::auth::PlayGamesAuthProvider::GetCredential(server_auth_code);
    firebase::Future<firebase::auth::User*> result =
        auth->SignInWithCredential(credential);
    
  3. ถ้าโปรแกรมของคุณมีห่วงปรับปรุงที่วิ่งอย่างสม่ำเสมอ (พูดวันที่ 30 หรือ 60 ครั้งต่อวินาที) คุณสามารถตรวจสอบผลครั้งต่อการปรับปรุงกับ Auth::SignInWithCredentialLastResult :

    firebase::Future<firebase::auth::User*> result =
        auth->SignInWithCredentialLastResult();
    if (result.status() == firebase::kFutureStatusComplete) {
      if (result.error() == firebase::auth::kAuthErrorNone) {
        firebase::auth::User* user = *result.result();
        printf("Sign in succeeded for `%s`\n", user->display_name().c_str());
      } else {
        printf("Sign in failed with error '%s'\n", result.error_message());
      }
    }

    หรือถ้าโปรแกรมของคุณเป็นเหตุการณ์ที่ขับเคลื่อนด้วยคุณอาจต้องการที่จะ ลงทะเบียนโทรกลับในอนาคต

ลงทะเบียนโทรกลับในอนาคต

บางโปรแกรมมี Update ฟังก์ชั่นที่เรียกว่า 30 หรือ 60 ครั้งต่อวินาที ตัวอย่างเช่น หลายเกมตามรุ่นนี้ โปรแกรมเหล่านี้สามารถเรียก LastResult ฟังก์ชั่นการโทรสำรวจความคิดเห็นไม่ตรงกัน อย่างไรก็ตาม หากโปรแกรมของคุณเป็นแบบขับเคลื่อนด้วยเหตุการณ์ คุณอาจต้องการลงทะเบียนฟังก์ชันเรียกกลับ ฟังก์ชันเรียกกลับถูกเรียกเมื่อเสร็จสิ้นอนาคต
void OnCreateCallback(const firebase::Future<firebase::auth::User*>& result,
                      void* user_data) {
  // The callback is called when the Future enters the `complete` state.
  assert(result.status() == firebase::kFutureStatusComplete);

  // Use `user_data` to pass-in program context, if you like.
  MyProgramContext* program_context = static_cast<MyProgramContext*>(user_data);

  // Important to handle both success and failure situations.
  if (result.error() == firebase::auth::kAuthErrorNone) {
    firebase::auth::User* user = *result.result();
    printf("Create user succeeded for email %s\n", user->email().c_str());

    // Perform other actions on User, if you like.
    firebase::auth::User::UserProfile profile;
    profile.display_name = program_context->display_name;
    user->UpdateUserProfile(profile);

  } else {
    printf("Created user failed with error '%s'\n", result.error_message());
  }
}

void CreateUser(firebase::auth::Auth* auth) {
  // Callbacks work the same for any firebase::Future.
  firebase::Future<firebase::auth::User*> result =
      auth->CreateUserWithEmailAndPasswordLastResult();

  // `&my_program_context` is passed verbatim to OnCreateCallback().
  result.OnCompletion(OnCreateCallback, &my_program_context);
}
ฟังก์ชั่นการโทรกลับยังสามารถเป็นแลมบ์ดาถ้าคุณชอบ
void CreateUserUsingLambda(firebase::auth::Auth* auth) {
  // Callbacks work the same for any firebase::Future.
  firebase::Future<firebase::auth::User*> result =
      auth->CreateUserWithEmailAndPasswordLastResult();

  // The lambda has the same signature as the callback function.
  result.OnCompletion(
      [](const firebase::Future<firebase::auth::User*>& result,
         void* user_data) {
        // `user_data` is the same as &my_program_context, below.
        // Note that we can't capture this value in the [] because std::function
        // is not supported by our minimum compiler spec (which is pre C++11).
        MyProgramContext* program_context =
            static_cast<MyProgramContext*>(user_data);

        // Process create user result...
        (void)program_context;
      },
      &my_program_context);
}

ขั้นตอนถัดไป

หลังจากที่ผู้ใช้ลงชื่อเข้าใช้เป็นครั้งแรก บัญชีผู้ใช้ใหม่จะถูกสร้างขึ้นและเชื่อมโยงกับรหัส Play Games ของพวกเขา บัญชีใหม่นี้จัดเก็บเป็นส่วนหนึ่งของโปรเจ็กต์ Firebase และใช้เพื่อระบุผู้ใช้ในทุกแอปในโปรเจ็กต์ของคุณ

ในเกมของคุณคุณจะได้รับของผู้ใช้ Firebase UID จาก firebase::auth::User วัตถุ:

firebase::auth::User* user = auth->current_user();
if (user != nullptr) {
  std::string playerName = user->displayName();

  // The user's ID, unique to the Firebase project.
  // Do NOT use this value to authenticate with your backend server,
  // if you have one. Use firebase::auth::User::Token() instead.
  std::string uid = user->uid();
}

ในฐานข้อมูล Firebase เรียลไทม์และการจัดเก็บเมฆกฎความปลอดภัย, คุณจะได้รับการลงนามใน ID ผู้ใช้ของผู้ใช้ที่ไม่ซ้ำกันจาก auth ตัวแปรและใช้ในการควบคุมสิ่งที่ข้อมูลที่เข้าถึงผู้ใช้สามารถ

เพื่อให้ได้ข้อมูลการเล่นเกมผู้เล่นของผู้ใช้หรือการบริการที่เข้าถึงเกมเล่นใช้ API ที่มีให้โดย บริการของ Google Play เกม c ++ SDK

ออกจากระบบผู้ใช้โทร SignOut() :

auth->SignOut();