Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

Аутентификация с помощью игровых сервисов Google Play на C ++

Вы можете использовать сервисы Google Play Games для входа игроков в игру для Android, созданную на Firebase и написанную на C ++. Чтобы использовать сервисы Google Play Games, войдите в систему с помощью Firebase, сначала войдите в проигрыватель с помощью Google Play Games и при этом запросите код аутентификации OAuth 2.0. Затем передайте код аутентификации в PlayGamesAuthProvider для создания Firebase верительных, который можно использовать для проверки подлинности Firebase.

Прежде чем вы начнете

Перед тем, как можно использовать Firebase аутентификации , вам необходимо:

  • Зарегистрируйте свой проект C ++ и настройте его для использования Firebase.

    Если ваш проект C ++ уже использует Firebase, значит, он уже зарегистрирован и настроен для Firebase.

  • Добавьте Firebase C ++ SDK для вашего проекта C ++.

Обратите внимание , что добавление Firebase к вашему C ++ проект включает в себя задачу , как в Firebase консоли и в вашем открытом проекте C ++ (например, загрузки Firebase конфигурационных файлов из консоли, а затем переместить их в C ++ проект).

Настройте свой проект Firebase

  1. Если вы еще не сделали, установить вашу игру SHA-1 отпечаток палец в настройках странице консоли Firebase.

    Вы можете получить SHA хэш вашего сертификата подписи с Gradle signingReport команды:

    ./gradlew signingReport

  2. Включите Google Play Games в качестве поставщика услуг входа:

    1. Найдите идентификатор клиента веб-сервера и секрет клиента. Идентификатор клиента веб-сервера идентифицирует ваш проект Firebase для серверов аутентификации Google Play.

      Чтобы найти эти значения:

      1. Откройте проект Firebase в консоли Google API , стр мандатной.
      2. В ИД клиента разделе OAuth 2.0, откройте веб - клиент (авто , созданный Google Service) Детали страницы. На этой странице перечислены идентификатор клиента и секрет вашего веб-сервера.
    2. Затем в консоли Firebase , откройте раздел Проверка подлинности.

    3. На вкладке Входа в методе, включите вход в Play Игры провайдера. Вам нужно будет указать идентификатор клиента веб-сервера вашего проекта и секрет клиента, которые вы получили из консоли API.

  1. В консоли Play Google , откройте приложение или создать.

  2. В разделе Grow, нажмите Play Игры Услуги> Настройка & Management> Конфигурация.

  3. Нажмите кнопку Да, моя игра уже использует Google API , выберите имя вашего проекта Firebase из списка и нажмите Использовать.

  4. На странице конфигурации игры Услуги Play, нажмите кнопку Добавить Credential.

    1. Выберите тип игрового сервера.
    2. В поле клиента OAuth, выберите веб - идентификатор клиента вашего проекта. Убедитесь, что это тот же идентификатор клиента, который вы указали при включении входа в Play Игры.
    3. Сохраните изменения.
  5. Тем не менее на странице конфигурации игры Услуги Play, нажмите кнопку Добавить Credential снова.

    1. Выберите Android тип.
    2. В поле клиента OAuth, выберите Android идентификатор клиента вашего проекта. (Если вы не видите свой идентификатор клиента Android, убедитесь, что вы установили отпечаток SHA-1 вашей игры в консоли Firebase.)
    3. Сохраните изменения.
  6. На странице тестировщиков, добавьте адреса электронной почты всех пользователей , которые должны быть в состоянии войти в вашу игру , прежде чем выпустить его на Play магазине.

Интегрируйте вход в Play Игры в свою игру

Прежде чем вы сможете регистрировать игроков в своей игре, вы должны интегрировать вход в Google Play Games.

Самый простой и рекомендуемый способ добавить поддержку для Play Игры входа в проект C ++ Android является использование Google для входа в систему C ++ SDK .

Чтобы добавить в игру вход в Play Games с помощью SDK для входа в Google C ++, выполните следующие действия:

  1. Клон или загрузить Google регистрации в Unity хранилищу плагин , который также содержит C ++ SDK.

  2. Постройте проект , содержащийся в staging/native/ каталоге, либо с помощью Android Studio или gradlew build .

    Построенные копирует свой вывод в каталог с именем google-signin-cpp в google-signin-cpp .

  3. Включите SDK C ++ для входа в Google в файл сборки собственного кода игры:

    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)
    

  4. Затем включите вспомогательный компонент 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:19.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. Тогда, в вашей игре, конфигурируют GoogleSignIn объект использования Play Games входа в систему и получить код сервера аутентификации:

    #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. Наконец, вызов для SignIn() в SignIn() , чтобы подписать игрока в играть в игры:

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

    Когда будущая возвращаемый SignIn() ПОСТАНОВЛЯЕТ, вы можете получить код сервера аутентификации из результата:

    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 Games, вы можете использовать код аутентификации для аутентификации в Firebase.

  1. После того, как игрок успешно вошел в систему с помощью Play Games, получите код авторизации для учетной записи игрока.

  2. Затем замените код аутентификации из сервисов Play Games на учетные данные Firebase и используйте учетные данные Firebase для аутентификации игрока:

    firebase::auth::Credential credential =
        firebase::auth::PlayGamesAuthProvider::GetCredential(server_auth_code);
    firebase::Future<firebase::auth::User*> result =
        auth->SignInWithCredential(credential);
    
  3. Если ваша программа имеет цикл обновления , который работает регулярно (скажем , в 30 или 60 раз в секунду), вы можете проверить результаты раз за обновление с 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());
      }
    }

    Или, если ваша программа приводится событие, вы можете предпочесть зарегистрировать обратный вызов на будущее .

Зарегистрируйте обратный звонок на будущее

Некоторые программы имеют Update функции, которые вызываются 30 или 60 раз в секунду. Например, многие игры следуют этой модели. Эти программы могут вызывать 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::User*> 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::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);
}

Следующие шаги

После того, как пользователь входит в систему в первый раз, создается новая учетная запись пользователя, привязанная к его идентификатору Play Games. Эта новая учетная запись хранится как часть вашего проекта Firebase и может использоваться для идентификации пользователя в каждом приложении в вашем проекте.

В вашей игре, вы можете получить пользователя Firebase UID из firebase::auth::User объекта:

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

В вашей базе данных в реальном времени и Firebase Cloud правил безопасности хранения, вы можете получить подписанный в уникальном пользователя идентификатор пользователя из auth переменной и использовать его , чтобы контролировать , какие данные пользователь заходит может.

Для того, чтобы получить информацию об игроке играть в игры пользователя или доступ Play Игры услуг, использовать API , предоставляемые в Google Play Игры услуги C ++ SDK .

Чтобы выйти пользователь, вызовите SignOut() :

auth->SignOut();