Firebase를 기반으로 C++로 개발된 Android 게임에서 플레이어가 Google Play 게임즈 서비스를 사용하여 로그인하도록 할 수 있습니다. Firebase에서 Google Play 게임즈 서비스 로그인을 사용하려면 우선 Google Play 게임즈에 플레이어를 로그인 처리하면서 OAuth 2.0 인증 코드를 요청합니다. 그런 다음 PlayGamesAuthProvider
에 인증 코드를 전달하여 Firebase 사용자 인증 정보를 생성합니다. 이 인증 정보를 사용하여 Firebase에 인증할 수 있습니다.
시작하기 전에
Firebase Authentication을 사용하려면 먼저 다음 작업을 해야 합니다.
C++ 프로젝트를 등록하고 Firebase를 사용하도록 구성합니다.
C++ 프로젝트에서 현재 Firebase를 사용하고 있다면 이미 등록되어 Firebase용으로 구성된 상태입니다.
C++ 프로젝트에 Firebase C++ SDK를 추가합니다.
C++ 프로젝트에 Firebase를 추가할 때 Firebase Console 및 열려 있는 C++ 프로젝트 모두에서 작업을 수행해야 합니다. 예를 들어 Console에서 Firebase 구성 파일을 다운로드한 후 이 파일을 C++ 프로젝트로 옮기는 작업이 필요합니다.
Firebase 프로젝트 설정
아직 설정하지 않았다면 Firebase Console의 설정 페이지에서 게임의 SHA-1 디지털 지문을 설정합니다.
Gradle
signingReport
명령어를 사용하여 서명 인증서의 SHA 해시를 가져올 수 있습니다../gradlew signingReport
Google Play Games를 로그인 제공업체로 사용 설정합니다.
Firebase Console에서 Authentication 섹션을 엽니다.
프로젝트의 웹 서버 클라이언트 ID와 클라이언트 보안 비밀번호를 생성하고 가져옵니다.
로그인 방법 탭에서 Google 로그인 제공업체를 사용 설정합니다.
Google 로그인 제공업체의 웹 서버 클라이언트 ID와 보안 비밀번호를 복사합니다.
로그인 방법 탭에서 Play Games 로그인 제공업체를 사용 설정하고 앞선 단계에서 얻은 프로젝트의 웹 서버 클라이언트 ID와 클라이언트 보안 비밀번호를 지정합니다.
Firebase 앱 정보로 Play Games services 구성
Google Play Console에서 Google Play 앱을 열거나 만듭니다.
성장 섹션에서 Play Games services > 설정 및 관리 > 구성을 클릭합니다.
예, 게임에서 이미 Google API를 사용하고 있습니다를 클릭하고 목록에서 Firebase 프로젝트를 선택한 후 사용을 클릭합니다.
Play Games services 구성 페이지에서 사용자 인증 정보 추가를 클릭합니다.
- 게임 서버 유형을 선택합니다.
- OAuth 클라이언트 입력란에서 프로젝트의 웹 클라이언트 ID를 선택합니다. 이 ID는 Play Games 로그인을 사용 설정할 때 지정한 클라이언트 ID와 일치해야 합니다.
- 변경사항을 저장합니다.
Play Games services 구성 페이지에서 다시 사용자 인증 정보 추가를 클릭합니다.
- Android 유형을 선택합니다.
- OAuth 클라이언트 입력란에서 프로젝트의 Android 클라이언트 ID를 선택합니다. (Android 클라이언트 ID가 표시되지 않는 경우 Firebase Console에서 게임의 SHA-1 디지털 지문을 설정해야 합니다.)
- 변경사항을 저장합니다.
테스터 페이지에서 Play Store에 게임을 출시하기 전에 게임에 로그인할 수 있어야 하는 사용자의 이메일 주소를 추가합니다.
게임에 Play 게임즈 로그인 통합
Google Play 게임즈 로그인을 통합해야 플레이어가 게임에 로그인할 수 있습니다.
Google 로그인 C++ SDK를 사용하면 C++ Android 프로젝트에 Play 게임즈 로그인 지원을 간편하게 추가할 수 있으며 이 방법이 권장됩니다.
Google 로그인 C++ SDK를 사용하여 게임에 Play 게임즈 로그인을 추가하려면 다음을 진행합니다.
C++ SDK도 포함된 Google 로그인 Unity 플러그인 저장소를 클론하거나 다운로드합니다.
Android 스튜디오나
gradlew build
를 사용하여staging/native/
디렉터리에 포함된 프로젝트를 빌드합니다.빌드가
google-signin-cpp
라는 디렉터리에 출력을 복사합니다.게임의 네이티브 코드 작성 파일에 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)
다음으로 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') }
그런 다음 게임에서 Play 게임즈 로그인을 사용하고 서버 인증 코드를 가져오도록
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);
마지막으로
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 게임즈에 로그인하면 인증 코드를 사용하여 Firebase에 인증할 수 있습니다.
플레이어가 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회)가 있는 경우 다음과 같이
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); }
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); }
다음 단계
사용자가 처음으로 로그인하면 신규 사용자 계정이 생성되어 사용자의 Play 게임즈 ID에 연결됩니다. 이 신규 계정은 Firebase 프로젝트에 저장되며 프로젝트의 모든 앱에서 사용자 식별에 사용할 수 있습니다.
게임에서 firebase::auth::User
객체로부터 사용자의 Firebase UID를 가져올 수 있습니다.
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();