Uwierzytelnij się za pomocą usług gier Google Play w języku C++

Za pomocą usług gier Google Play możesz logować graczy do gry na Androida zbudowanej w oparciu o Firebase i napisanej w języku C++. Aby korzystać z usług Gier Google Play, zaloguj się za pomocą Firebase, najpierw zaloguj się w odtwarzaczu za pomocą Gier Google Play i poproś o kod autoryzacji OAuth 2.0. Następnie przekaż kod autoryzacyjny do PlayGamesAuthProvider , aby wygenerować dane uwierzytelniające Firebase, których możesz użyć do uwierzytelnienia w Firebase.

Zanim zaczniesz

Zanim będziesz mógł skorzystać z uwierzytelniania Firebase , musisz:

  • Zarejestruj swój projekt C++ i skonfiguruj go do korzystania z Firebase.

    Jeśli Twój projekt C++ korzysta już z Firebase, oznacza to, że jest już zarejestrowany i skonfigurowany dla Firebase.

  • Dodaj pakiet SDK Firebase C++ do swojego projektu C++.

Pamiętaj, że dodanie Firebase do projektu C++ obejmuje zadania zarówno w konsoli Firebase , jak i w otwartym projekcie C++ (na przykład pobierasz pliki konfiguracyjne Firebase z konsoli, a następnie przenosisz je do projektu C++).

Skonfiguruj projekt Firebase

  1. Jeśli jeszcze tego nie zrobiłeś, ustaw odcisk palca SHA-1 swojej gry na stronie Ustawienia konsoli Firebase.

    Możesz uzyskać skrót SHA swojego certyfikatu podpisującego za pomocą polecenia stopniowego signingReport :

    ./gradlew signingReport

  2. Włącz Gry Google Play jako dostawcę logowania:

    1. W konsoli Firebase otwórz sekcję Uwierzytelnianie .

    2. Wygeneruj i uzyskaj identyfikator klienta serwera WWW oraz klucz tajny klienta:

      1. Na karcie Metoda logowania włącz dostawcę logowania Google .

      2. Skopiuj identyfikator klienta serwera internetowego i klucz tajny od dostawcy logowania Google .

    3. Na karcie Metoda logowania włącz dostawcę logowania do Gier Play i podaj identyfikator klienta serwera WWW swojego projektu oraz klucz tajny klienta, które otrzymałeś w ostatnim kroku.

Skonfiguruj usługi gier Play przy użyciu informacji o aplikacji Firebase

  1. W Konsoli Google Play otwórz aplikację Google Play lub utwórz ją.

  2. W sekcji Rozwój kliknij Usługi gier Play > Konfiguracja i zarządzanie > Konfiguracja .

  3. Kliknij Tak, moja gra już korzysta z interfejsów API Google , wybierz z listy swój projekt Firebase, a następnie kliknij Użyj .

  4. Na stronie konfiguracji usług Gier Play kliknij Dodaj dane uwierzytelniające .

    1. Wybierz typ serwera gier .
    2. W polu Klient OAuth wybierz identyfikator klienta internetowego swojego projektu. Upewnij się, że jest to ten sam identyfikator klienta, który podałeś podczas włączania logowania w Grach Play.
    3. Zapisz zmiany.
  5. Wciąż na stronie konfiguracji usług Gier Play kliknij ponownie Dodaj dane uwierzytelniające .

    1. Wybierz typ Androida .
    2. W polu Klient OAuth wybierz identyfikator klienta Androida swojego projektu. (Jeśli nie widzisz swojego identyfikatora klienta Androida, upewnij się, że ustawiłeś odcisk palca SHA-1 swojej gry w konsoli Firebase.)
    3. Zapisz zmiany.
  6. Na stronie Testerzy dodaj adresy e-mail wszystkich użytkowników, którzy muszą mieć możliwość zalogowania się do Twojej gry, zanim udostępnisz ją w Sklepie Play.

Zintegruj logowanie się do Gier Play ze swoją grą

Zanim będziesz mógł logować graczy do swojej gry, musisz zintegrować logowanie do Gier Google Play.

Najłatwiejszym i zalecanym sposobem dodania obsługi logowania się w Grach Play do projektu w języku C++ na Androida jest użycie zestawu SDK do logowania się przez Google w języku C++ .

Aby dodać logowanie do Gier Play do swojej gry przy użyciu pakietu SDK logowania Google C++, wykonaj następujące czynności:

  1. Sklonuj lub pobierz repozytorium wtyczek Google Sign-in Unity , które zawiera również pakiet SDK języka C++.

  2. Zbuduj projekt zawarty w katalogu staging/native/ , używając Android Studio lub gradlew build .

    Kompilacja kopiuje swoje dane wyjściowe do katalogu o nazwie google-signin-cpp .

  3. Dołącz pakiet SDK logowania Google w języku C++ do pliku kodu natywnego gry:

    CMake

    W pliku CMakeLists.txt najwyższego poziomu:

    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

    W pliku 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. Następnie dołącz komponent pomocniczy Java, który jest wymagany przez zestaw SDK języka C++.

    Aby to zrobić, w pliku build.gradle na poziomie projektu dodaj katalog wyjściowy kompilacji pakietu SDK jako repozytorium lokalne:

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

    W pliku build.gradle na poziomie modułu zadeklaruj komponent pomocniczy jako zależność:

    dependencies {
        implementation 'com.google.android.gms:play-services-auth:21.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. Następnie w grze skonfiguruj obiekt GoogleSignIn , aby korzystał z logowania do Gier Play i pobierał kod autoryzacyjny serwera:

    #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. Na koniec wywołaj SignIn() , aby zalogować gracza do Gier Play:

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

    Kiedy przyszłość zwrócona przez SignIn() zostanie rozwiązana, możesz uzyskać kod autoryzacji serwera z wyniku:

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

Uwierzytelnij się w Firebase

Gdy gracz zaloguje się w Grach Play, możesz użyć kodu uwierzytelniającego, aby uwierzytelnić się w Firebase.

  1. Gdy gracz pomyślnie zaloguje się w Grach Play, uzyskaj kod autoryzacyjny do konta gracza.

  2. Następnie wymień kod autoryzacyjny z usług Gier Play na dane uwierzytelniające Firebase i użyj danych uwierzytelniających Firebase, aby uwierzytelnić gracza:

    firebase::auth::Credential credential =
        firebase::auth::PlayGamesAuthProvider::GetCredential(server_auth_code);
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInAndRetrieveDataWithCredential(credential);
    
  3. Jeśli Twój program ma pętlę aktualizacji, która działa regularnie (powiedzmy 30 lub 60 razy na sekundę), możesz sprawdzić wyniki raz na aktualizację za pomocą 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());
      }
    }

    Lub, jeśli Twój program jest sterowany zdarzeniami, możesz preferować zarejestrowanie wywołania zwrotnego w Future .

Zarejestruj oddzwonienie w przyszłości

Niektóre programy mają funkcje Update , które są wywoływane 30 lub 60 razy na sekundę. Na przykład wiele gier podąża za tym modelem. Programy te mogą wywoływać funkcje LastResult w celu odpytywania wywołań asynchronicznych. Jeśli jednak Twój program jest sterowany zdarzeniami, możesz preferować zarejestrowanie funkcji wywołania zwrotnego. Funkcja wywołania zwrotnego jest wywoływana po zakończeniu przyszłości.
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);
}
Jeśli wolisz, funkcją wywołania zwrotnego może być także 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);
}

Następne kroki

Gdy użytkownik zaloguje się po raz pierwszy, zostanie utworzone nowe konto użytkownika i powiązane z jego identyfikatorem w Grach Play. To nowe konto jest przechowywane jako część Twojego projektu Firebase i może służyć do identyfikowania użytkownika w każdej aplikacji w Twoim projekcie.

W swojej grze możesz uzyskać identyfikator UID użytkownika Firebase z obiektu 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();
}

W regułach bezpieczeństwa bazy danych Firebase Realtime i Cloud Storage możesz uzyskać unikalny identyfikator zalogowanego użytkownika ze zmiennej auth i użyć go do kontrolowania, do jakich danych użytkownik może uzyskać dostęp.

Aby uzyskać informacje o odtwarzaczu Gier Play lub uzyskać dostęp do usług Gier Play, użyj interfejsów API udostępnianych przez pakiet SDK usług Gier Google Play w języku C++ .

Aby wylogować użytkownika, wywołaj SignOut() :

auth->SignOut();