Melakukan Autentikasi dengan Firebase menggunakan Akun Berbasis Sandi menggunakan C++

Anda dapat menggunakan Firebase Authentication untuk mengizinkan pengguna melakukan autentikasi dengan Firebase menggunakan alamat email dan sandi, serta mengelola akun berbasis sandi di aplikasi Anda.

Sebelum memulai

  1. Tambahkan Firebase ke project C++ Anda.
  2. Dalam file build.gradle level project, pastikan Anda memasukkan repositori Maven Google di bagian buildscript dan allprojects.
  3. Jika Anda belum menghubungkan aplikasi ke project Firebase, lakukanlah dari Firebase console.
  4. Aktifkan login dengan Email/Sandi:
    1. Di Firebase console, buka bagian Auth.
    2. Di tab Metode login, aktifkan metode login dengan Email/sandi lalu klik Simpan.

Mengakses class firebase::auth::Auth

Class Auth adalah gateway untuk semua panggilan API.
  1. Tambahkan file header Auth dan Aplikasi:
    #include "firebase/app.h"
    #include "firebase/auth.h"
    
  2. Pada kode inisialisasi Anda, buat class 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. Dapatkan class firebase::auth::Auth untuk firebase::App Anda. Terdapat fungsi pemetaan one-to-one antara App dan Auth.
    firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);
    

Membuat akun berbasis sandi

Untuk membuat akun pengguna baru dengan sandi, lakukan langkah-langkah berikut dalam kode login aplikasi Anda:

  1. Ketika pengguna baru mendaftar menggunakan formulir pendaftaran aplikasi Anda, selesaikan langkah-langkah validasi akun baru yang diwajibkan oleh aplikasi, seperti memverifikasi bahwa sandi akun baru tersebut telah diketik dengan benar dan memenuhi persyaratan kerumitan.
  2. Buat akun baru dengan meneruskan alamat email dan sandi pengguna baru ke Auth::CreateUserWithEmailAndPassword:
    firebase::Future<firebase::auth::User*> result =
        auth->CreateUserWithEmailAndPassword(email, password);
    
  3. Jika program Anda memiliki loop update yang berjalan secara teratur (misalnya 30 atau 60 kali per detik), Anda dapat memeriksa hasilnya satu kali per update dengan Auth::CreateUserWithEmailAndPasswordLastResult:
    firebase::Future<firebase::auth::User*> result =
        auth->CreateUserWithEmailAndPasswordLastResult();
    if (result.status() == firebase::kFutureStatusComplete) {
      if (result.error() == firebase::auth::kAuthErrorNone) {
        firebase::auth::User* user = *result.result();
        printf("Create user succeeded for email %s\n", user->email().c_str());
      } else {
        printf("Created user failed with error '%s'\n", result.error_message());
      }
    }
    
    Atau, jika program Anda dikendalikan oleh peristiwa, Anda bisa memilih untuk mendaftarkan callback pada Future.

Membuat pengguna login dengan alamat email dan sandi

Langkah-langkah untuk membuat agar pengguna login dengan sandi mirip dengan langkah-langkah untuk membuat akun baru. Dalam fungsi login aplikasi Anda, lakukan hal berikut:

  1. Ketika pengguna login ke aplikasi Anda, teruskan alamat email dan sandi pengguna ke firebase::auth::Auth::SignInWithEmailAndPassword:
    firebase::Future<firebase::auth::User*> result =
        auth->SignInWithEmailAndPassword(email, password);
    
  2. Jika program Anda memiliki loop update yang berjalan secara teratur (misalnya 30 atau 60 kali per detik), Anda dapat memeriksa hasilnya satu kali per update dengan Auth::SignInWithEmailAndPasswordLastResult:
    firebase::Future<firebase::auth::User*> result =
        auth->SignInWithEmailAndPasswordLastResult();
    if (result.status() == firebase::kFutureStatusComplete) {
      if (result.error() == firebase::auth::kAuthErrorNone) {
        firebase::auth::User* user = *result.result();
        printf("Sign in succeeded for email %s\n", user->email().c_str());
      } else {
        printf("Sign in failed with error '%s'\n", result.error_message());
      }
    }
    
    Atau, jika program Anda dikendalikan oleh peristiwa, Anda bisa memilih untuk mendaftarkan callback pada Future.

Mendaftarkan callback pada Future

Beberapa program memiliki fungsi Update yang dipanggil sebanyak 30 atau 60 kali per detik. Misalnya, banyak game mengikuti model ini. Program ini dapat memanggil fungsi LastResult untuk melakukan polling pada panggilan asinkron. Namun, jika program Anda dikendalikan oleh peristiwa, Anda dapat memilih untuk mendaftarkan fungsi callback. Fungsi callback dipanggil setelah selesainya 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::User*> result =
      auth->CreateUserWithEmailAndPasswordLastResult();

  // `&my_program_context` is passed verbatim to OnCreateCallback().
  result.OnCompletion(OnCreateCallback, &my_program_context);
}
Fungsi callback juga bisa menjadi lambda, jika Anda menginginkannya.
void CreateUserUsingLambda(firebase::auth::Auth* auth) {
  // Callbacks work the same for any firebase::Future.
  firebase::Future<firebase::auth::User*> 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);
}

Langkah berikutnya

Setelah pengguna login untuk pertama kalinya, akun pengguna baru akan dibuat dan ditautkan ke kredensial, yaitu nama pengguna dan sandi, nomor telepon, atau informasi penyedia autentikasi, yang digunakan pengguna tersebut untuk login. Akun baru ini disimpan sebagai bagian dari project Firebase Anda, dan dapat digunakan untuk mengidentifikasi pengguna di setiap aplikasi dalam project, terlepas dari cara pengguna login.

  • Di aplikasi, Anda bisa mendapatkan informasi profil dasar pengguna dari objek firebase::auth::User:

    firebase::auth::User* user = auth->current_user();
    if (user != nullptr) {
      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();
    }
    
  • Di Aturan Keamanan Firebase Realtime Database dan Cloud Storage, Anda bisa mendapatkan ID pengguna unik yang login dari variabel auth, dan menggunakannya untuk mengontrol data yang dapat diakses oleh pengguna.

Anda dapat mengizinkan pengguna untuk login ke aplikasi menggunakan beberapa penyedia autentikasi dengan menautkan kredensial penyedia autentikasi ke akun pengguna yang ada.

Agar pengguna logout, panggil SignOut():

auth->SignOut();