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

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

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

  1. เพิ่ม Firebase ลงในโปรเจ็กต์ C++
  2. ในคอนโซล Firebase ให้ไปที่ ความปลอดภัย > การตรวจสอบสิทธิ์
  3. ในแท็บวิธีการลงชื่อเข้าใช้ ให้เปิดใช้ผู้ให้บริการการลงชื่อเข้าใช้Twitter
  4. เพิ่มคีย์ API และ API Secret จากคอนโซลนักพัฒนาแอปของผู้ให้บริการดังกล่าว ลงในการกำหนดค่าของผู้ให้บริการ โดยทำดังนี้:
    1. ลงทะเบียนแอปของคุณในฐานะแอปพลิเคชันสำหรับนักพัฒนาแอปบน Twitter และรับคีย์ API และ API Secret ของ OAuth สำหรับแอป
    2. ตรวจสอบว่าได้ตั้งค่า URI การเปลี่ยนเส้นทาง OAuth ของ Firebase (เช่น my-app-12345.firebaseapp.com/__/auth/handler) เป็น URL เรียกกลับการให้สิทธิ์ ในหน้าการตั้งค่าของแอป ในการ กำหนดค่าแอป Twitter
  5. คลิกบันทึก

เข้าถึงชั้นเรียน 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. ทำตาม เอกสารประกอบการลงชื่อเข้าใช้ด้วย Twitter เพื่อรับโทเค็นเพื่อการเข้าถึง OAuth และข้อมูลลับของ OAuth
  2. หลังจากที่ผู้ใช้ลงชื่อเข้าใช้เรียบร้อยแล้ว ให้แลกเปลี่ยนโทเค็นและข้อมูลลับเป็นข้อมูลเข้าสู่ระบบ Firebase แล้วตรวจสอบสิทธิ์กับ Firebase โดยใช้ข้อมูลเข้าสู่ระบบ Firebase
    firebase::auth::Credential credential =
        firebase::auth::TwitterAuthProvider::GetCredential(token, secret);
    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 เพื่อสำรวจการเรียกแบบไม่พร้อมกัน อย่างไรก็ตาม หากโปรแกรมของคุณขับเคลื่อนด้วยเหตุการณ์ คุณอาจต้องการลงทะเบียนฟังก์ชันการเรียกกลับ ระบบจะเรียกใช้ฟังก์ชัน 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();