Firebase.Auth.PhoneAuthProvider

Use phone number text messages to authenticate.

Summary

Allows developers to use the phone number and SMS verification codes to authenticate a user.

The verification flow results in a Credential that can be used to,

  • Sign in to an existing phone number account/sign up with a new phone number
  • Link a phone number to a current user. This provider will be added to the user.
  • Update a phone number on an existing user.
  • Re-authenticate an existing user. This may be needed when a sensitive operation requires the user to be recently logged in.

Possible verification flows: (1) User manually enters verification code.

  • App calls VerifyPhoneNumber.
  • Web verification page is displayed to user where they may need to solve a CAPTCHA. [iOS only].
  • Auth server sends the verification code via SMS to the provided phone number. App recieves verification id via Listener::OnCodeSent().
  • User receives SMS and enters verification code in app's GUI.
  • App uses user's verification code to call PhoneAuthProvider::GetCredential.

(2) SMS is automatically retrieved (Android only).

  • App calls VerifyPhoneNumber with timeout_ms > 0.
  • Auth server sends the verification code via SMS to the provided phone number.
  • SMS arrives and is automatically retrieved by the operating system. Credential is automatically created and passed to the app via Listener::OnVerificationCompleted().

(3) Phone number is instantly verified (Android only).

  • App calls VerifyPhoneNumber.
  • The operating system validates the phone number without having to send an SMS. Credential is automatically created and passed to the app via Listener::OnVerificationCompleted().

All three flows can be handled with the example code below. The flow is complete when PhoneVerifier::credential() returns non-NULL.

class PhoneVerifier : public PhoneAuthProvider::Listener {
 public:
  PhoneVerifier(const char* phone_number,
                PhoneAuthProvider* phone_auth_provider)
    : display_message_("Sending SMS with verification code"),
      display_verification_code_input_box_(false),
      display_resend_sms_button_(false),
      phone_auth_provider_(phone_auth_provider),
      phone_number_(phone_number) {
    SendSms();
  }

  ~PhoneVerifier() override {}

  void OnVerificationCompleted(Credential credential) override {
    // Grab `mutex_` for the scope of `lock`. Callbacks can be called on
    // other threads, so this mutex ensures data access is atomic.
    MutexLock lock(mutex_);
    credential_ = credential;
  }

  void OnVerificationFailed(const std::string& error) override {
    MutexLock lock(mutex_);
    display_message_ = "Verification failed with error: " + error;
  }

  void OnCodeSent(const std::string& verification_id,
                  const PhoneAuthProvider::ForceResendingToken&
                      force_resending_token) override {
    MutexLock lock(mutex_);
    verification_id_ = verification_id;
    force_resending_token_ = force_resending_token;

    display_verification_code_input_box_ = true;
    display_message_ = "Waiting for SMS";
  }

  void OnCodeAutoRetrievalTimeOut(
      const std::string& verification_id) override {
    MutexLock lock(mutex_);
    display_resend_sms_button_ = true;
  }

  // Draw the verification GUI on screen and process input events.
  void Draw() {
    MutexLock lock(mutex_);

    // Draw an informative message describing what's currently happening.
    ShowTextBox(display_message_.c_str());

    // Once the time out expires, display a button to resend the SMS.
    // If the button is pressed, call VerifyPhoneNumber again using the
    // force_resending_token_.
    if (display_resend_sms_button_ && !verification_id_.empty()) {
      const bool resend_sms = ShowTextButton("Resend SMS");
      if (resend_sms) {
        SendSms();
      }
    }

    // Once the SMS has been sent, allow the user to enter the SMS
    // verification code into a text box. When the user has completed
    // entering it, call GetCredential() to complete the flow.
    if (display_verification_code_input_box_) {
      const std::string verification_code =
        ShowInputBox("Verification code");
      if (!verification_code.empty()) {
        credential_ = phone_auth_provider_->GetCredential(
            verification_id_.c_str(), verification_code.c_str());
      }
    }
  }

  // The phone number verification flow is complete when this returns
  // non-NULL.
  Credential* credential() {
    MutexLock lock(mutex_);
    return credential_.is_valid() ? &credential_ : nullptr;
  }

 private:
  void SendSms() {
    static const uint32_t kAutoVerifyTimeOut = 2000;
    MutexLock lock(mutex_);
    phone_auth_provider_->VerifyPhoneNumber(
        phone_number_.c_str(), kAutoVerifyTimeOut, &force_resending_token_,
        this);
    display_resend_sms_button_ = false;
  }

  // GUI-related variables.
  std::string display_message_;
  bool display_verification_code_input_box_;
  bool display_resend_sms_button_;

  // Phone flow related variables.
  PhoneAuthProvider* phone_auth_provider_;
  std::string phone_number_;
  std::string verification_id_;
  PhoneAuthProvider::ForceResendingToken force_resending_token_;
  Credential credential_;

  // Callbacks can be called on other threads, so guard them with a mutex.
  Mutex mutex_;
};

Inheritance

Inherits from: SystemIDisposable

Properties

MaxTimeoutMs
static uint
Maximum value of autoVerifyTimeOutMs in VerifyPhoneNumber.

Public functions

Dispose()
void
VerificationCompleted(Credential credential)
delegate void
Callback used when phone number auto-verification succeeded.

Properties

MaxTimeoutMs

static uint MaxTimeoutMs

Maximum value of autoVerifyTimeOutMs in VerifyPhoneNumber.

VerifyPhoneNumber will automatically clamp values to this amount.

Public functions

Dispose

void Dispose()

VerificationCompleted

delegate void VerificationCompleted(
  Credential credential
)

Callback used when phone number auto-verification succeeded.

Send feedback about...

Need help? Visit our support page.