ตรวจสอบสิทธิ์โดยใช้ Google Sign-In และ C++

คุณสามารถอนุญาตให้ผู้ใช้ตรวจสอบสิทธิ์กับ Firebase โดยใช้บัญชี Google ของตนเองได้ด้วยการผสานรวม Google Sign-In เข้ากับแอป

ก่อนเริ่มต้น

  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. หลังจากที่ผู้ใช้ลงชื่อเข้าใช้สำเร็จแล้ว ให้แลกเปลี่ยนโทเค็นรหัสเป็นข้อมูลเข้าสู่ระบบ 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. หากโปรแกรมมีลูปการอัปเดตที่ทำงานเป็นประจำ (เช่น 30 หรือ 60 ครั้งต่อวินาที) คุณสามารถตรวจสอบผลลัพธ์ได้ 1 ครั้งต่อการอัปเดตด้วย 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());
      }
    }
    หรือหากโปรแกรมของคุณขับเคลื่อนด้วยเหตุการณ์ คุณอาจต้องการ ลงทะเบียน Callback ใน Future

ลงทะเบียน Callback ใน Future

บางโปรแกรมมีฟังก์ชัน Update ที่เรียกใช้ 30 หรือ 60 ครั้งต่อวินาที เช่น เกมจำนวนมากใช้โมเดลนี้ โปรแกรมเหล่านี้สามารถเรียกใช้ฟังก์ชัน LastResult เพื่อโพลการเรียกแบบไม่พร้อมกัน อย่างไรก็ตาม หากโปรแกรมของคุณขับเคลื่อนด้วยเหตุการณ์ คุณอาจต้องการลงทะเบียนฟังก์ชัน Callback ระบบจะเรียกใช้ฟังก์ชัน Callback เมื่อ 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);
}
ฟังก์ชัน Callback ยังเป็น 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 และใช้เพื่อระบุผู้ใช้ในทุกแอปในโปรเจ็กต์ได้ ไม่ว่าผู้ใช้จะลงชื่อเข้าใช้ด้วยวิธีใดก็ตาม

  • ในแอป คุณสามารถรับข้อมูลโปรไฟล์พื้นฐานของผู้ใช้ได้จากออบเจ็กต์ 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();