اصالت‌سنجی بااستفاده از «ورود به سیستم با Google» و C++‎

با ادغام «ورود به سیستم با Google» در برنامه‌تان، می‌توانید به کاربران اجازه دهید بااستفاده از «حساب‌های Google» خودشان با Firebase اصالت‌سنجی کنند.

قبل از شروع

  1. ‫Firebase را به پروژه C++‎ خود اضافه کنید.
  2. ‫Google را به‌عنوان ارائه‌دهنده ورود به سیستم برای پروژه Firebase خود فعال کنید:
    1. در کنسول Firebase، به امنیت > اصالت‌سنجی بروید.
    2. در برگه روش ورود به سیستم، ارائه‌دهنده ورود به سیستم Google را فعال کنید.
    3. روی ذخیره کردن کلیک کنید.
  3. فایل پیکربندی Firebase خود را به‌روز کنید.

    1. وقتی در کنسول Firebase درخواست شد، فایل پیکربندی Firebase به‌روزشده (google-services.json) را بارگیری کنید که اکنون حاوی اطلاعات کارخواه OAuth موردنیاز برای ورود به سیستم Google است.

    2. این فایل پیکربندی به‌روزشده را به پروژه «استودیو Android» خود منتقل کنید و فایل پیکربندی مربوطه را که اکنون قدیمی شده است جایگزین کنید. (به افزودن Firebase به پروژه Android مراجعه کنید.)

دسترسی به کلاس firebase::auth::Auth

کلاس Auth دروازه همه فراخوانی‌های API است.
  1. فایل‌های سرصفحه Auth و App را اضافه کنید:
    #include <cassert>
    #include <cstdint>
    
    #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. پس‌از اینکه کاربر باموفقیت به سیستم وارد شد، نمودار شناسایی را با اطلاعات اعتباری Firebase مبادله کنید و بااستفاده از اطلاعات اعتباری Firebase، با Firebase اصالت‌سنجی کنید:
    firebase::auth::Credential credential =
        firebase::auth::GoogleAuthProvider::GetCredential(google_id_token,
                                                          nullptr);
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInAndRetrieveDataWithCredential(credential);
  3. اگر برنامه شما حلقه به‌روزرسانی دارد که به‌طور منظم (مثلاً ۳۰ یا ۶۰ بار در ثانیه) اجرا می‌شود، می‌توانید نتایج را یک‌بار در هر به‌روزرسانی با 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

برخی‌از برنامه‌ها Update کارکرد دارند که در هر ثانیه ۳۰ یا ۶۰ بار فراخوانده می‌شوند. برای مثال، بسیاری از بازی‌ها از این مدل پیروی می‌کنند. این برنامه‌ها می‌توانند توابع LastResult را برای نظرسنجی تماس‌های ناهمزمان فراخوانی کنند. بااین‌حال، اگر برنامه شما رویدادمحور است، ممکن است ترجیح دهید کارکردهای برگشتی را ثبت کنید. پس‌از تکمیل «آینده»، تابع برگشتی فراخوانی می‌شود.
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();