אימות באמצעות Twitter ו-C++

כדי לאפשר למשתמשים לבצע אימות ב-Firebase באמצעות חשבונות Twitter שלהם, אפשר לשלב את אימות Twitter באפליקציה.

לפני שמתחילים

  1. מוסיפים את Firebase לפרויקט C++.
  2. במסוף Firebase, פותחים את הקטע Auth.
  3. בכרטיסייה Sign in method (שיטת כניסה), מפעילים את הספק Twitter.
  4. מוסיפים את מפתח ה-API ואת הסוד API מ-Developer Console של הספק הזה אל תצורת ספק:
    1. רישום האפליקציה בתור אפליקציה למפתחים ב-Twitter ולקבל את מפתח ה-API של OAuth של האפליקציה ו-API Secret.
    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());
      }
    }
    לחלופין, אם התוכנית שלכם מבוססת על אירועים, תוכלו לרשום קריאה חוזרת (callback) ב-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);
}
אם אתם מעדיפים, פונקציית הקריאה החוזרת יכולה גם להיות 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();