使用 Google 登录服务和 C++ 进行身份验证
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
您可以将 Google 登录服务集成到您的应用中,让您的用户使用自己的 Google 账号进行 Firebase 身份验证。
准备工作
- 将 Firebase 添加至您的 C++ 项目。
- 在 Firebase 控制台中启用 Google 登录方法:
- 在 Firebase 控制台中,打开 Auth 部分。
- 在登录方法标签页中,启用 Google 登录方法并点击保存。
- 在控制台中出现提示时,下载更新后的 Firebase 配置文件 (
google-services.json
),该文件现在包含进行 Google 登录所需的 OAuth 客户端信息。
- 将此更新后的配置文件转移到您的 Android Studio 项目中,替换掉现已过时的相应配置文件。(请参阅将 Firebase 添加到您的 Android 项目。)
访问 firebase::auth::Auth
类
Auth
类是所有 API 调用都需要通过的门户。
- 添加 Auth 和 App 头文件:
#include "firebase/app.h"
#include "firebase/auth.h"
- 在您的初始化代码中,创建一个
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__)
- 获取您的
firebase::App
对应的 firebase::auth::Auth
类。App
和 Auth
是一对一的映射关系。firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);
进行 Firebase 身份验证
- 分别按照适用于 Android 和 iOS+ 的说明,获取用于进行 Google 登录的 ID 令牌。
- 在用户成功登录之后,用 ID 令牌换取 Firebase 凭据,然后使用此 Firebase 凭据进行 Firebase 身份验证:
firebase::auth::Credential credential =
firebase::auth::GoogleAuthProvider::GetCredential(google_id_token,
nullptr);
firebase::Future<firebase::auth::AuthResult> result =
auth->SignInAndRetrieveDataWithCredential(credential);
- 如果您的程序有定期(如每秒 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);
}
如果您愿意,回调函数也可以是一个 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);
}
后续步骤
在用户首次登录后,系统会创建一个新的用户账号,并将其与该用户登录时使用的凭据(即用户名和密码、电话号码或者身份验证提供方信息)相关联。此新账号存储在您的 Firebase 项目中,无论用户采用何种方式登录,您项目中的每个应用都可以使用此账号来识别用户。
您可以通过将身份验证提供方凭据关联至现有用户账号,让用户可以使用多个身份验证提供方登录您的应用。
如需将用户退出登录,请调用 SignOut()
:
auth->SignOut();
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-08-16。
[null,null,["最后更新时间 (UTC):2025-08-16。"],[],[],null,["You can let your users authenticate with Firebase using their Google Accounts by\nintegrating Google Sign-In into your app.\n\nBefore you begin\n\n1. [Add Firebase to your C++ project](/docs/cpp/setup#note_select_platform).\n2. Enable Google as a sign-in method in the Firebase console:\n 1. In the [Firebase console](//console.firebase.google.com/), open the **Auth** section.\n 2. On the **Sign in method** tab, enable the **Google** sign-in method and click **Save**.\n3. When prompted in the console, download the updated Firebase config file (`google-services.json`), which now contains the OAuth client information required for Google sign-in.\n4. Move this updated config file into your Android Studio project, *replacing* the now-outdated corresponding config file. (See [Add Firebase to your Android project](/docs/android/setup#add-config-file).)\n\nAccess the `firebase::auth::Auth` class The `Auth` class is the gateway for all API calls.\n\n1. Add the Auth and App header files: \n\n ```c++\n #include \"firebase/app.h\"\n #include \"firebase/auth.h\"\n ```\n2. In your initialization code, create a [`firebase::App`](/docs/reference/cpp/class/firebase/app) class. \n\n ```c++\n #if defined(__ANDROID__)\n firebase::App* app =\n firebase::App::Create(firebase::AppOptions(), my_jni_env, my_activity);\n #else\n firebase::App* app = firebase::App::Create(firebase::AppOptions());\n #endif // defined(__ANDROID__)\n ```\n3. Acquire the `firebase::auth::Auth` class for your `firebase::App`. There is a one-to-one mapping between `App` and `Auth`. \n\n ```c++\n firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);\n ```\n\nAuthenticate with Firebase\n\n1. Follow instructions for [Android](/docs/auth/android/google-signin#authenticate_with_firebase) and [iOS+](/docs/auth/ios/google-signin#2_implement_google_sign-in) to get an ID token for the Google sign in.\n2. After a user successfully signs in, exchange the ID token for a Firebase credential, and authenticate with Firebase using the Firebase credential: \n\n ```c++\n firebase::auth::Credential credential =\n firebase::auth::GoogleAuthProvider::GetCredential(google_id_token,\n nullptr);\n firebase::Future\u003cfirebase::auth::AuthResult\u003e result =\n auth-\u003eSignInAndRetrieveDataWithCredential(credential);\n ```\n3. If your program has an update loop that runs regularly (say at 30 or 60 times per second), you can check the results once per update with `Auth::SignInAndRetrieveDataWithCredentialLastResult`: \n\n ```c++\n firebase::Future\u003cfirebase::auth::AuthResult\u003e result =\n auth-\u003eSignInAndRetrieveDataWithCredentialLastResult();\n if (result.status() == firebase::kFutureStatusComplete) {\n if (result.error() == firebase::auth::kAuthErrorNone) {\n firebase::auth::AuthResult auth_result = *result.result();\n printf(\"Sign in succeeded for `%s`\\n\",\n auth_result.user.display_name().c_str());\n } else {\n printf(\"Sign in failed with error '%s'\\n\", result.error_message());\n }\n }\n ```\n Or, if your program is event driven, you may prefer to [register a callback on the\n Future](#register_callback_on_future).\n\nRegister a callback on a Future Some programs have `Update` functions that are called 30 or 60 times per second. For example, many games follow this model. These programs can call the `LastResult` functions to poll asynchronous calls. However, if your program is event driven, you may prefer to register callback functions. A callback function is called upon completion of the Future. \n\n```c++\nvoid OnCreateCallback(const firebase::Future\u003cfirebase::auth::User*\u003e& result,\n void* user_data) {\n // The callback is called when the Future enters the `complete` state.\n assert(result.status() == firebase::kFutureStatusComplete);\n\n // Use `user_data` to pass-in program context, if you like.\n MyProgramContext* program_context = static_cast\u003cMyProgramContext*\u003e(user_data);\n\n // Important to handle both success and failure situations.\n if (result.error() == firebase::auth::kAuthErrorNone) {\n firebase::auth::User* user = *result.result();\n printf(\"Create user succeeded for email %s\\n\", user-\u003eemail().c_str());\n\n // Perform other actions on User, if you like.\n firebase::auth::User::UserProfile profile;\n profile.display_name = program_context-\u003edisplay_name;\n user-\u003eUpdateUserProfile(profile);\n\n } else {\n printf(\"Created user failed with error '%s'\\n\", result.error_message());\n }\n}\n\nvoid CreateUser(firebase::auth::Auth* auth) {\n // Callbacks work the same for any firebase::Future.\n firebase::Future\u003cfirebase::auth::AuthResult\u003e result =\n auth-\u003eCreateUserWithEmailAndPasswordLastResult();\n\n // `&my_program_context` is passed verbatim to OnCreateCallback().\n result.OnCompletion(OnCreateCallback, &my_program_context);\n}\n```\nThe callback function can also be a lambda, if you prefer. \n\n```c++\nvoid CreateUserUsingLambda(firebase::auth::Auth* auth) {\n // Callbacks work the same for any firebase::Future.\n firebase::Future\u003cfirebase::auth::AuthResult\u003e result =\n auth-\u003eCreateUserWithEmailAndPasswordLastResult();\n\n // The lambda has the same signature as the callback function.\n result.OnCompletion(\n [](const firebase::Future\u003cfirebase::auth::User*\u003e& result,\n void* user_data) {\n // `user_data` is the same as &my_program_context, below.\n // Note that we can't capture this value in the [] because std::function\n // is not supported by our minimum compiler spec (which is pre C++11).\n MyProgramContext* program_context =\n static_cast\u003cMyProgramContext*\u003e(user_data);\n\n // Process create user result...\n (void)program_context;\n },\n &my_program_context);\n}\n```\n\nNext steps\n\nAfter a user signs in for the first time, a new user account is created and\nlinked to the credentials---that is, the user name and password, phone\nnumber, or auth provider information---the user signed in with. This new\naccount is stored as part of your Firebase project, and can be used to identify\na user across every app in your project, regardless of how the user signs in.\n\n- In your apps, you can get the user's basic profile information from the\n [`firebase::auth::User`](/docs/reference/cpp/class/firebase/auth/user) object:\n\n ```c++\n firebase::auth::User user = auth-\u003ecurrent_user();\n if (user.is_valid()) {\n std::string name = user.display_name();\n std::string email = user.email();\n std::string photo_url = user.photo_url();\n // The user's ID, unique to the Firebase project.\n // Do NOT use this value to authenticate with your backend server,\n // if you have one. Use firebase::auth::User::Token() instead.\n std::string uid = user.uid();\n }\n ```\n- In your Firebase Realtime Database and Cloud Storage\n [Security Rules](/docs/database/security/user-security), you can\n get the signed-in user's unique user ID from the `auth` variable,\n and use it to control what data a user can access.\n\nYou can allow users to sign in to your app using multiple authentication\nproviders by [linking auth provider credentials to an\nexisting user account.](/docs/auth/cpp/account-linking)\n\nTo sign out a user, call [`SignOut()`](/docs/reference/cpp/class/firebase/auth/auth#signout): \n\n```c++\nauth-\u003eSignOut();\n```"]]