Buka konsol

Melakukan Autentikasi Menggunakan Layanan Google Play Game dengan C++

Anda dapat menggunakan layanan Google Play Game untuk menyediakan fitur login bagi pemain untuk masuk ke game Android yang dibuat di Firebase dan ditulis di C++. Untuk menggunakan fitur login layanan Google Play Game dengan Firebase, pemain harus login terlebih dahulu dengan Google Play Game dan meminta kode autentikasi OAuth 2.0. Kemudian, teruskan kode autentikasi ke PlayGamesAuthProvider untuk membuat kredensial Firebase yang dapat Anda gunakan untuk melakukan autentikasi dengan Firebase.

Sebelum memulai

Sebelum dapat menggunakan Firebase Authentication, Anda harus:

  • Mendaftarkan project C++ Anda dan mengonfigurasikannya untuk menggunakan Firebase.

    Jika project C++ Anda telah menggunakan Firebase, berarti project tersebut telah terdaftar dan dikonfigurasikan untuk Firebase.

  • Pada file build.gradle level project, pastikan untuk menyertakan repositori Maven Google di bagian buildscript dan allprojects Anda.

  • Tambahkan Firebase C++ SDK ke project C++ Anda.

Perlu diperhatikan bahwa penambahan Firebase ke project C++ Anda melibatkan tugas di Firebase console dan di project C++ terbuka (misalnya, Anda mendownload file konfigurasi Firebase dari konsol, lalu memindahkannya ke project C++).

Menyiapkan project Firebase Anda

  1. Jika Anda belum melakukannya, setel sidik jari SHA-1 game Anda di halaman Setelan pada Firebase console.

    Anda bisa mendapatkan sidik jari SHA-1 pada kunci dengan perintah keytool:

    keytool -exportcert -list -v \
        -alias YOUR-KEY-NAME -keystore PATH-TO-KEYSTORE

  2. Aktifkan Google Play Game sebagai penyedia login:

    1. Temukan ID klien dan rahasia klien server web project Anda. ID klien server web mengidentifikasi project Firebase Anda ke server autentikasi Google Play.

      Untuk menemukan nilai ini:

      1. Buka project Firebase Anda di halaman kredensial konsol Google API.
      2. Di bagian ID klien OAuth 2.0, buka halaman detail Klien web (dibuat secara otomatis oleh Layanan Google). Halaman ini mencantumkan ID dan rahasia klien server web Anda.
    2. Kemudian, di Firebase console, buka bagian Authentication.

    3. Pada tab Metode login, aktifkan penyedia login Play Game. Anda perlu menetapkan ID klien dan rahasia klien server web project Anda, yang Anda dapatkan dari konsol API.

  1. Buka konsol Google Play lalu klik Layanan game.
  2. Klik Tambahkan game baru. Pada dialog game baru, klik Saya sudah menggunakan Google API di game saya, lalu klik nama project Firebase Anda pada daftar. Pilih kategori game, lalu klik Lanjutkan untuk membuka halaman Detail Game.
  3. Di akhir halaman Detail Game, pastikan semua API yang diperlukan sudah diaktifkan.
  4. Selanjutnya, buka halaman Aplikasi yang ditautkan dan klik Android. Tentukan nama package game Anda, dan klik Simpan dan lanjutkan. Konsol akan menampilkan ID klien Android Anda. Anda dapat mengabaikan nilai ini.
  5. Di halaman Pengujian, beri akses kepada alamat email pengguna yang perlu login ke game Anda sebelum dirilis di Play Store.

Mengintegrasikan fitur login Play Game ke game Anda

Agar pemain dapat login ke game Anda, Anda harus mengintegrasikan fitur login Google Play Game.

Cara termudah dan direkomendasikan untuk menambahkan dukungan login Play Game ke project C++ Android adalah dengan menggunakan Google Sign-in C++ SDK.

Untuk menambahkan fitur login Play Game ke game Anda menggunakan Google Sign-in C++ SDK, lakukan langkah berikut:

  1. Clone atau download repositori plugin Google Sign-in Unity, yang juga berisi C ++ SDK.

  2. Buat project yang terkandung pada direktori staging/native/, dengan menggunakan Android Studio atau gradlew build.

    Build akan menyalin outputnya ke direktori yang bernama google-signin-cpp.

  3. Sertakan Google Sign-in C++ SDK dalam file pembuatan kode native game Anda:

    CMake

    Pada file CMakeLists.txt tingkat atas Anda:

    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

    Pada file Android.mk Anda:

    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. Berikutnya, sertakan komponen Java helper yang diperlukan oleh C++ SDK.

    Untuk melakukannya, pada file build.gradle tingkat project Anda, tambahkan direktori output build SDK sebagai repositori lokal:

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

    Dan, dalam file build.gradle tingkat modul Anda, umumkan komponen helper sebagai dependensi:

    dependencies {
        implementation 'com.google.android.gms:play-services-auth:17.0.0'
        // 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. Kemudian, pada game Anda, konfigurasikan objek GoogleSignIn untuk menggunakan fitur login Play Game dan mengambil kembali kode autentikasi server:

    #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. Terakhir, panggil SignIn() untuk membuat pemain login ke Play Game:

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

    Saat Future yang ditampilkan oleh SignIn() selesai, Anda bisa mendapatkan kode autentikasi server dari hasil:

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

Melakukan autentikasi dengan Firebase

Setelah pemain login dengan Play Game, Anda dapat menggunakan kode autentikasi untuk melakukan autentikasi dengan Firebase.

  1. Setelah pemain berhasil login menggunakan Play Game, dapatkan kode autentikasi untuk akun pemain tersebut.

  2. Kemudian, tukarkan kode autentikasi dari layanan Play Game untuk mendapatkan kredensial Firebase, dan gunakan kredensial Firebase tersebut untuk mengautentikasi pemain:

    firebase::auth::Credential credential =
        firebase::auth::PlayGamesAuthProvider::GetCredential(server_auth_code);
    firebase::Future<firebase::auth::User*> result =
        auth->SignInWithCredential(credential);
    
  3. Jika program Anda memiliki loop update yang berjalan secara teratur (misalnya 30 atau 60 kali per detik), Anda bisa memeriksa hasilnya satu kali per update dengan 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());
      }
    }

    Atau, jika program Anda dikendalikan oleh peristiwa, Anda bisa memilih untuk mendaftarkan callback pada Future.

Mendaftarkan callback pada Future

Beberapa program memiliki fungsi Update yang dipanggil sebanyak 30 atau 60 kali per detik. Misalnya, banyak game mengikuti model ini. Program ini bisa memanggil fungsi LastResult untuk mengumpulkan panggilan asinkron. Namun, jika program Anda dikendalikan oleh peristiwa, Anda dapat memilih untuk mendaftarkan fungsi callback. Fungsi callback dipanggil setelah selesainya Future.
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);
}
Fungsi callback juga bisa menjadi lambda, jika Anda menginginkannya.
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);
}

Langkah berikutnya

Setelah pengguna login untuk pertama kalinya, akun pengguna baru akan dibuat dan terhubung ke ID Play Game miliknya. Akun baru ini disimpan sebagai bagian dari project Firebase Anda, dan dapat digunakan untuk mengidentifikasi pengguna di setiap aplikasi dalam project Anda.

Di game Anda, Anda bisa mendapatkan UID Firebase pengguna dari objek 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();
}

Dalam Aturan Keamanan Firebase Realtime Database dan Cloud Storage Anda, Anda bisa mendapatkan ID unik milik pengguna yang login dari variabel auth, dan menggunakannya untuk mengontrol data yang dapat diakses pengguna.

Untuk mendapatkan informasi pemain Play Game milik pengguna atau untuk mengakses layanan Play Game, gunakan API yang diberikan oleh C++ SDK layanan Google Play Game.

Agar pengguna logout, panggil SignOut():

auth->SignOut();