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

Sie können die Dienste von Google Play Games verwenden, um Spieler bei einem Android-Spiel anzumelden, das auf Firebase basiert und in C++ geschrieben ist. Um die Anmeldung bei den Google Play Games-Diensten mit Firebase zu nutzen, melden Sie den Player zunächst 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, die Sie zur Authentifizierung bei Firebase verwenden 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 offenen C++-Projekt erfordert (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 gradle signingReport abrufen:

    ./gradlew signingReport

  2. Aktivieren Sie Google Play Games als Anmeldeanbieter:

    1. Öffnen Sie in der Firebase-Konsole den Abschnitt „Authentifizierung“ .

    2. Generieren und erhalten Sie die Webserver-Client-ID und das Client-Geheimnis Ihres Projekts:

      1. Aktivieren Sie auf der Registerkarte „Anmeldemethode“ den Google -Anmeldeanbieter.

      2. Kopieren Sie die Client-ID und das Geheimnis des Webservers vom Google -Anmeldeanbieter.

    3. Aktivieren Sie auf der Registerkarte „Anmeldemethode“ den Anmeldeanbieter „Play Games“ und geben Sie die Webserver-Client-ID und das Client-Geheimnis Ihres Projekts an, die Sie im letzten Schritt 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 Anmeldeinformationen hinzufügen .

    1. Wählen Sie den Gameservertyp aus.
    2. Wählen Sie im Feld „OAuth-Client“ die Web-Client-ID Ihres Projekts aus. Stellen Sie sicher, dass es sich um dieselbe Client-ID handelt, die Sie angegeben haben, als Sie die Play Games-Anmeldung aktiviert haben.
    3. Speichern Sie Ihre Änderungen.
  5. Klicken Sie immer noch auf der Konfigurationsseite der Play Games-Dienste erneut auf Anmeldeinformationen 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, stellen Sie sicher, dass Sie den SHA-1-Fingerabdruck Ihres Spiels in der Firebase-Konsole festgelegt haben.)
    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 müssen müssen, bevor Sie es im Play Store veröffentlichen.

Integrieren Sie die Play Games-Anmeldung in Ihr Spiel

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

Die einfachste und empfohlene Möglichkeit, einem C++-Android-Projekt Unterstützung für die Play Games-Anmeldung hinzuzufügen, ist die Verwendung des Google Sign-in C++ SDK .

Gehen Sie wie folgt vor, um die Play Games-Anmeldung mit dem Google Sign-in C++ SDK zu Ihrem Spiel 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 gradlew build .

    Der Build kopiert seine Ausgabe in ein Verzeichnis mit dem Namen google-signin-cpp .

  3. Fügen Sie das Google Sign-in C++ SDK in die native Code-Make-Datei 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. Fügen Sie als Nächstes die Java-Hilfskomponente ein, die für das C++ SDK erforderlich ist.

    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'
            }
        }
    }
    

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

    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. Konfigurieren Sie dann in Ihrem Spiel ein GoogleSignIn Objekt, um die Play Games-Anmeldung zu verwenden und einen Serverauthentifizierungscode 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 abschließend SignIn() auf, um den Spieler bei Play Games anzumelden:

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

    Wenn die von SignIn() zurückgegebene Zukunft aufgelöst wird, können Sie den Serverauthentifizierungscode 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 den Authentifizierungscode zur Authentifizierung bei Firebase verwenden.

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

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

    firebase::auth::Credential credential =
        firebase::auth::PlayGamesAuthProvider::GetCredential(server_auth_code);
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInAndRetrieveDataWithCredential(credential);
    
  3. Wenn Ihr Programm über eine Aktualisierungsschleife verfügt, die regelmäßig ausgeführt wird (z. B. 30 oder 60 Mal pro Sekunde), können Sie die Ergebnisse einmal pro Aktualisierung mit 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());
      }
    }
    überprüfen

    Oder wenn Ihr Programm ereignisgesteuert ist, möchten Sie vielleicht lieber einen Rückruf auf der Future registrieren .

Registrieren Sie einen Rückruf für einen Future

Einige Programme verfügen über 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, möchten Sie möglicherweise lieber Rückruffunktionen registrieren. Nach Abschluss der Zukunft 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::AuthResult> result =
      auth->CreateUserWithEmailAndPasswordLastResult();

  // `&my_program_context` is passed verbatim to OnCreateCallback().
  result.OnCompletion(OnCreateCallback, &my_program_context);
}
Die Callback-Funktion kann bei Bedarf auch ein Lambda sein.
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);
}

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 zur Identifizierung eines Benutzers in jeder App in Ihrem Projekt verwendet werden.

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

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

In Ihren Firebase-Echtzeitdatenbank- und Cloud-Speicher-Sicherheitsregeln können Sie die eindeutige Benutzer-ID des angemeldeten Benutzers aus der auth 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 Sie SignOut() auf:

auth->SignOut();