Authentifizieren Sie sich mithilfe von Google Play Games Services mit C++

Sie können Google Play Games-Dienste verwenden, um Spieler bei einem Android-Spiel anzumelden, das auf Firebase basiert und in C++ geschrieben ist. Um die Google Play Games-Dienste zu verwenden, melden Sie sich mit Firebase an, melden Sie sich zuerst mit dem Player bei Google Play Games an und fordern Sie dabei einen OAuth 2.0-Authentifizierungscode an. Übergeben Sie dann den Authentifizierungscode an PlayGamesAuthProvider , um Firebase-Anmeldeinformationen zu generieren, mit denen Sie sich bei Firebase authentifizieren können.

Bevor Sie beginnen

Bevor Sie die Firebase-Authentifizierung verwenden können, müssen Sie Folgendes tun:

  • Registrieren Sie Ihr C++-Projekt und konfigurieren Sie es für die Verwendung von Firebase.

    Wenn Ihr C++-Projekt Firebase bereits verwendet, ist es bereits für Firebase registriert und konfiguriert.

  • Fügen Sie das Firebase C++ SDK zu Ihrem C++-Projekt hinzu.

Beachten Sie, dass das Hinzufügen von Firebase zu Ihrem C++-Projekt Aufgaben sowohl in der Firebase-Konsole als auch in Ihrem geöffneten C++-Projekt umfasst (Sie laden beispielsweise Firebase-Konfigurationsdateien von der Konsole herunter und verschieben sie dann in Ihr C++-Projekt).

Richten Sie Ihr Firebase-Projekt ein

  1. Falls noch nicht geschehen, legen Sie den SHA-1-Fingerabdruck Ihres Spiels auf der Seite „ Einstellungen “ der Firebase-Konsole fest.

    Sie können den SHA-Hash Ihres Signaturzertifikats mit dem Befehl signingReport signingReport abrufen:

    ./gradlew signingReport

  2. Aktivieren Sie Google Play Games als Anmeldeanbieter:

    1. Finden Sie die Webserver-Client-ID und das Client-Geheimnis Ihres Projekts. Die Webserver-Client-ID identifiziert Ihr Firebase-Projekt gegenüber den Google Play-Authentifizierungsservern.

      So finden Sie diese Werte:

      1. Öffnen Sie Ihr Firebase-Projekt auf der Anmeldeseite der Google APIs-Konsole .
      2. Öffnen Sie im Abschnitt OAuth 2.0-Client-IDs die Detailseite des Webclients (automatisch vom Google-Dienst erstellt) . Diese Seite listet Ihre Webserver-Client-ID und Ihr Geheimnis auf.
    2. Öffnen Sie dann in der Firebase-Konsole den Abschnitt Authentifizierung .

    3. Aktivieren Sie auf der Registerkarte Anmeldemethode den Play Spiele - Anmeldeanbieter . Sie müssen die Webserver-Client-ID und das Clientgeheimnis Ihres Projekts angeben, die Sie von der APIs-Konsole erhalten haben.

Konfigurieren Sie Play Games-Dienste mit Ihren Firebase-App-Informationen

  1. Öffnen Sie in der Google Play Console Ihre Google Play App oder erstellen Sie eine.

  2. Klicken Sie im Abschnitt Erweitern auf Play Games-Dienste > Einrichtung und Verwaltung > Konfiguration .

  3. Klicken Sie auf Ja, mein Spiel verwendet bereits Google-APIs , wählen Sie Ihr Firebase-Projekt aus der Liste aus und klicken Sie dann auf Verwenden .

  4. Klicken Sie auf der Konfigurationsseite der Play Games-Dienste auf Anmeldedaten hinzufügen .

    1. Wählen Sie den Spielservertyp aus .
    2. Wählen Sie im Feld OAuth-Client die Web-Client-ID Ihres Projekts aus. Stellen Sie sicher, dass dies die gleiche Client-ID ist, die Sie bei der Aktivierung der Play Games-Anmeldung angegeben haben.
    3. Speichern Sie Ihre Änderungen.
  5. Klicken Sie auf der Konfigurationsseite der Play Games-Dienste erneut auf Anmeldedaten hinzufügen .

    1. Wählen Sie den Android -Typ aus.
    2. Wählen Sie im Feld OAuth-Client die Android-Client-ID Ihres Projekts aus. (Wenn Sie Ihre Android-Client-ID nicht sehen, achten Sie darauf, den SHA-1-Fingerabdruck Ihres Spiels in der Firebase-Konsole festzulegen.)
    3. Speichern Sie Ihre Änderungen.
  6. Fügen Sie auf der Seite Tester die E-Mail-Adressen aller Benutzer hinzu, die sich bei Ihrem Spiel anmelden können müssen, bevor Sie es im Play Store veröffentlichen.

Integrieren Sie die Play Games-Anmeldung in Ihr Spiel

Bevor Sie Spieler bei Ihrem Spiel anmelden können, müssen Sie die Google Play Games-Anmeldung integrieren.

Die einfachste und empfohlene Methode zum Hinzufügen von Unterstützung für die Anmeldung bei Play Games zu einem C++-Android-Projekt ist die Verwendung des Google Sign-in C++ SDK .

Gehen Sie wie folgt vor, um Ihrem Spiel mithilfe des Google Sign-in C++ SDK eine Play Games-Anmeldung hinzuzufügen:

  1. Klonen oder laden Sie das Google Sign-in Unity-Plugin-Repository herunter, das auch das C++ SDK enthält.

  2. Erstellen Sie das im Verzeichnis staging/native/ enthaltene Projekt entweder mit Android Studio oder mit gradlew build .

    Der Build kopiert seine Ausgabe in ein Verzeichnis namens google-signin-cpp .

  3. Fügen Sie das C++-SDK für die Google-Anmeldung in die Erstellungsdatei für den nativen Code Ihres Spiels ein:

    CMake

    In Ihrer CMakeLists.txt -Datei der obersten Ebene:

    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

    In Ihrer Android.mk -Datei:

    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. Schließen Sie als Nächstes die Java-Hilfskomponente ein, die vom C++ SDK benötigt wird.

    Fügen Sie dazu in Ihrer build.gradle -Datei auf Projektebene das SDK-Build-Ausgabeverzeichnis als lokales Repository hinzu:

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

    Deklarieren Sie in Ihrer build.gradle -Datei auf Modulebene die Hilfskomponente als Abhängigkeit:

    dependencies {
        implementation 'com.google.android.gms:play-services-auth:20.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')
    }
    
  5. Konfigurieren Sie dann in Ihrem Spiel ein GoogleSignIn -Objekt, um die Play Games-Anmeldung zu verwenden und einen Server-Authentifizierungscode abzurufen:

    #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. Rufen Sie schließlich SignIn() auf, um den Spieler bei Play Games anzumelden:

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

    Wenn das von SignIn() zurückgegebene Future aufgelöst wird, können Sie den Server-Authentifizierungscode aus dem Ergebnis abrufen:

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

Authentifizieren Sie sich mit Firebase

Nachdem sich der Spieler bei Play Games angemeldet hat, können Sie sich mit dem Authentifizierungscode bei Firebase authentifizieren.

  1. Nachdem sich der Spieler erfolgreich mit Play Games angemeldet hat, erhalten Sie einen Authentifizierungscode für das Konto des Spielers.

  2. Tauschen Sie dann den Authentifizierungscode von Play Games-Diensten gegen Firebase-Anmeldedaten aus und verwenden Sie die Firebase-Anmeldedaten, um den Spieler zu authentifizieren:

    firebase::auth::Credential credential =
        firebase::auth::PlayGamesAuthProvider::GetCredential(server_auth_code);
    firebase::Future<firebase::auth::User*> result =
        auth->SignInWithCredential(credential);
    
  3. Wenn Ihr Programm eine Update-Schleife hat, die regelmäßig läuft (z. B. 30 oder 60 Mal pro Sekunde), können Sie die Ergebnisse einmal pro Update mit 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());
      }
    }
    überprüfen

    Wenn Ihr Programm ereignisgesteuert ist, können Sie es vorziehen, einen Rückruf auf Future zu registrieren .

Registrieren Sie einen Rückruf auf einem Future

Einige Programme haben Update -Funktionen, die 30 oder 60 Mal pro Sekunde aufgerufen werden. Viele Spiele folgen beispielsweise diesem Modell. Diese Programme können die LastResult Funktionen aufrufen, um asynchrone Aufrufe abzufragen. Wenn Ihr Programm jedoch ereignisgesteuert ist, können Sie es vorziehen, Callback-Funktionen zu registrieren. Nach Abschluss des Futures wird eine Callback-Funktion aufgerufen.
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);
}
Die Callback-Funktion kann auf Wunsch auch ein Lambda sein.
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);
}

Nächste Schritte

Nachdem sich ein Benutzer zum ersten Mal angemeldet hat, wird ein neues Benutzerkonto erstellt und mit seiner Play Games-ID verknüpft. Dieses neue Konto wird als Teil Ihres Firebase-Projekts gespeichert und kann verwendet werden, um einen Benutzer in jeder App in Ihrem Projekt zu identifizieren.

In Ihrem Spiel können Sie die Firebase-UID des Benutzers aus dem Objekt firebase::auth::User abrufen:

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

In Ihren Firebase-Echtzeitdatenbank- und Cloudspeicher-Sicherheitsregeln können Sie die eindeutige Benutzer-ID des angemeldeten Benutzers aus der auth -Variable abrufen und damit steuern, auf welche Daten ein Benutzer zugreifen kann.

Um die Play Games-Spielerinformationen eines Nutzers abzurufen oder auf Play Games-Dienste zuzugreifen, verwenden Sie die APIs, die vom C++ SDK der Google Play Games-Dienste bereitgestellt werden.

Um einen Benutzer abzumelden, rufen SignOut() :

auth->SignOut();