您可以使用 Google Play 遊戲服務讓玩家登入 Android 遊戲
建構而成如何使用 Google Play 遊戲服務登入功能
請先使用 Google Play 遊戲登入玩家,再要求接收
驗證 OAuth 2.0 驗證碼。接著,將驗證碼傳遞至
PlayGamesAuthProvider
產生 Firebase 憑證,您可以使用該憑證執行以下操作
進行驗證
事前準備
使用前 Firebase Authentication、 請完成下列操作:
註冊 C++ 專案,並將其設為使用 Firebase。
如果您的 C++ 專案已使用 Firebase,表示該專案已註冊, 設定 Firebase 專屬的容器
在 C++ 專案中新增 Firebase C++ SDK。
請注意,將 Firebase 新增至 C++ 專案時,需要執行 Firebase 控制台,然後在開啟的 C++ 專案中 (例如,下載 控制台中的 Firebase 設定檔,然後將這些檔案移至 C++ 專案)。
設定 Firebase 專案
如果您尚未設定遊戲的 SHA-1 指紋,請先在 「設定」頁面 Firebase控制台中就能保留這項資訊
您可以使用 Gradle 取得簽署憑證的 SHA 雜湊
signingReport
指令:./gradlew signingReport
將 Google Play Games 設為登入提供者:
在 Firebase 控制台中,開啟 Authentication 專區。
產生並取得專案的網路伺服器用戶端 ID 和用戶端 密鑰:
在「Sign in method」分頁中啟用 Google 登入功能 。
複製 Google 登入中的網路伺服器用戶端 ID 和密鑰 。
在「Sign in method」分頁中啟用 Play Games ,並指定專案的網路伺服器用戶端 ID,然後 用戶端密碼。
使用 Firebase 應用程式資訊設定 Play Games services
在 Google Play 控制台, 請開啟或建立一個「Google Play」應用程式。
在「拓展」部分中,按一下 Play Games services >設定和管理 >設定。
按一下「是,我的遊戲已在使用 Google API」,選取您的 Firebase 然後按一下「使用」。
在 Play Games services 設定頁面中按一下 新增憑證。
- 選取「遊戲伺服器」類型。
- 在「OAuth 用戶端」欄位中,選取專案的網路用戶端 ID。成為 這是您啟用功能時指定的用戶端 ID 目前登入次數:Play Games。
- 儲存變更。
在「Play Games services」設定頁面,按一下 重新新增憑證。
- 選取「Android」類型。
- 在「OAuth 用戶端」欄位中,選取專案的 Android 用戶端 ID。 (如果找不到您的 Android 用戶端 ID,請確認您已設定遊戲的 Firebase 控制台中的 SHA-1 指紋)。
- 儲存變更。
在「測試人員」頁面中,為需要測試的使用者新增電子郵件地址 。 Play Store。
將 Play 遊戲登入程序整合至遊戲
您必須先整合 Google Play,才能讓玩家登入遊戲 遊戲登入。
如要在 C++ 中新增 Play 遊戲登入支援功能,這是最簡單的建議方式 Android 專案是使用 Google 登入 C++ SDK。
如要使用 Google 登入 C++ SDK 將 Play 遊戲登入機制新增至遊戲,請 包括:
複製或下載 Google 登入 Unity 外掛程式存放區。 其中也包含 C++ SDK
使用以下方法建立
staging/native/
目錄中包含的專案: Android Studio 或gradlew build
建構作業會將輸出內容複製到名為
google-signin-cpp
的目錄。在遊戲的原生程式碼 make 檔案中加入 Google 登入 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)
接下來,請加入 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:21.2.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') }
然後,在遊戲中設定
GoogleSignIn
物件以使用 Play 遊戲 登入以及擷取伺服器驗證碼:#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);
最後,呼叫
SignIn()
以簽署玩家的 Play 遊戲:Future<GoogleSignIn::SignInResult> &future = gsi.SignIn();
解析
SignIn()
傳回的 Future 後,您就可以取得伺服器驗證 傳回的結果: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 遊戲後,您可以使用這組驗證碼 進行驗證
玩家成功使用 Play 遊戲登入後,取得驗證 代碼。
接著,使用 Play 遊戲服務交換驗證碼以供 Firebase 使用 憑證,並使用 Firebase 憑證驗證玩家:
firebase::auth::Credential credential = firebase::auth::PlayGamesAuthProvider::GetCredential(server_auth_code); firebase::Future<firebase::auth::AuthResult> result = auth->SignInAndRetrieveDataWithCredential(credential);
如果您的程式有定期執行的更新迴圈 (例如 30 或 60) 每秒可執行 1 次
Auth::SignInAndRetrieveDataWithCredentialLastResult
:firebase::Future<firebase::auth::AuthResult> result = auth->SignInAndRetrieveDataWithCredentialLastResult(); if (result.status() == firebase::kFutureStatusComplete) { if (result.error() == firebase::auth::kAuthErrorNone) { firebase::auth::AuthResult auth_result = *result.result(); printf("Sign in succeeded for `%s`\n", auth_result.user.display_name().c_str()); } else { printf("Sign in failed with error '%s'\n", result.error_message()); } }
或者,如果您的計畫是依據事件推動,建議您 在 Future 註冊回呼。
在 Future 上註冊回呼
某些程式包含可呼叫每秒 30 或 60 次的Update
函式。
舉例來說,許多遊戲都採用這個模型。這些程式可以呼叫 LastResult
函式來輪詢非同步呼叫。
不過,如果您的程式是以事件驅動,建議您註冊回呼函式。
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::AuthResult> result = auth->CreateUserWithEmailAndPasswordLastResult(); // `&my_program_context` is passed verbatim to OnCreateCallback(). result.OnCompletion(OnCreateCallback, &my_program_context); }如有需要,回呼函式也可以是 lambda。
void CreateUserUsingLambda(firebase::auth::Auth* auth) { // Callbacks work the same for any firebase::Future. firebase::Future<firebase::auth::AuthResult> 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); }
後續步驟
使用者首次登入後,系統會建立新的使用者帳戶 連結 Google Play 遊戲。這個新帳戶會儲存在您的 Firebase 專案的專用 ID,可用來識別應用程式內所有應用程式的使用者 專案。
在遊戲中,您可以透過
firebase::auth::User
物件:
firebase::auth::User user = auth->current_user();
if (user.is_valid()) {
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 即時資料庫和 Cloud Storage 安全性規則中,您可以
已登入使用者在 auth
變數中的不重複使用者 ID,並使用該 ID 來
控制使用者可以存取哪些資料
如要取得使用者的 Play 遊戲玩家資訊或存取 Play 遊戲服務, 使用 Google Play 遊戲服務 C++ SDK 提供的 API。
如要將使用者登出,請呼叫 SignOut()
:
auth->SignOut();