Аутентификация с использованием входа в Google и C++

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

Прежде чем начать

  1. Добавьте Firebase в свой проект на C++ .
  2. Включите Google в качестве способа входа в систему в консоли Firebase :
    1. В консоли Firebase откройте раздел «Аутентификация» .
    2. На вкладке «Способ входа» включите вход через Google и нажмите «Сохранить» .
  3. При появлении соответствующего запроса в консоли загрузите обновленный конфигурационный файл Firebase ( google-services.json ), который теперь содержит информацию о клиенте OAuth, необходимую для входа через Google.
  4. Переместите этот обновленный конфигурационный файл в свой проект Android Studio, заменив им устаревший соответствующий конфигурационный файл. (См. раздел «Добавление Firebase в ваш проект Android» .)

Получите доступ к классу firebase::auth::Auth

Класс Auth является шлюзом для всех вызовов API.
  1. Добавьте заголовочные файлы Auth и App:
    #include "firebase/app.h"
    #include "firebase/auth.h"
  2. В коде инициализации создайте класс firebase::App .
    #if defined(__ANDROID__)
      firebase::App* app =
          firebase::App::Create(firebase::AppOptions(), my_jni_env, my_activity);
    #else
      firebase::App* app = firebase::App::Create(firebase::AppOptions());
    #endif  // defined(__ANDROID__)
  3. Получите класс firebase::auth::Auth для вашего firebase::App . Между классами App и Auth существует однозначное соответствие.
    firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);

Аутентификация с помощью Firebase

  1. Следуйте инструкциям для Android и iOS+ , чтобы получить токен идентификации для входа в Google.
  2. После успешного входа пользователя в систему обменяйте токен ID на учетные данные Firebase и выполните аутентификацию в Firebase, используя эти учетные данные:
    firebase::auth::Credential credential =
        firebase::auth::GoogleAuthProvider::GetCredential(google_id_token,
                                                          nullptr);
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInAndRetrieveDataWithCredential(credential);
  3. Если в вашей программе есть цикл обновления, который выполняется регулярно (например, 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

В некоторых программах есть функции 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::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);
}

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

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

  • В ваших приложениях вы можете получить основную информацию профиля пользователя из объекта firebase::auth::User :

    firebase::auth::User user = auth->current_user();
    if (user.is_valid()) {
      std::string name = user.display_name();
      std::string email = user.email();
      std::string photo_url = user.photo_url();
      // 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 Realtime Database и Cloud Storage вы можете получить уникальный идентификатор пользователя, вошедшего в систему, из переменной auth и использовать его для управления доступом пользователя к данным.

Вы можете разрешить пользователям входить в ваше приложение, используя несколько поставщиков аутентификации, связав учетные данные поставщика аутентификации с существующей учетной записью пользователя.

Для выхода пользователя из системы вызовите SignOut() :

auth->SignOut();