We all know that feeling. You don’t have a concrete idea about the solution you are looking for and you want to see a quick answer for your question. So, check the short answer below:

Short answer to your question

Very short answer is a “NO”. Firebase PhoneAuthProvider does not deliver a resend SMS feature in its SDK for JavaScript developers (as of now, June-2019). It actually supports such feature for Android, C++ and Unity developers via PhoneAuthProvider.ForceResendingToken, but the same is not available for JavaScript developers. Therefore, if you’d like to create a “Resend SMS Verification” button for your web application, you should implement it yourself by initialising a new recaptcha session (like setting window.recaptchaVerifier etc…), using a separate recaptcha container (such as <div id=”recaptcha-container-resend” />) and eventually calling signInWithPhoneNumber(…) function again on user interaction.

Long answer to your question

The screenshot below shows you the documentation of Firebase services in various platforms. You may access the Javascript SDK reference by clicking the link below:

https://firebase.google.com/docs/reference/js

Screenshot 2019-06-16 at 17.12.00

To implement a resend SMS feature on my ReactJS app, I went through this documentation. And I realised that there wasn’t any resend SMS support by Firebase.auth. Interestingly, there was no blog or stackoverflow ticket discussing the issue either. Then, I assumed that the developers, who came across with the same problem, silently implemented a resend SMS feature by simply re-initialising the whole process on their web applications. Therefore, I decided to break this silence by writing this post and helping future developers (and maybe even future self 🙂 ).

Assume that your application shows two components to the user. First component will receive the phone number from the user and after the SMS is sent, the second component will demand the user to type in the verification code.

Your first component should run following methods in order:

  1. Initialize recaptcha
    • window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier(…);
  2. Sign in with given phone number
    • auth.signInWithPhoneNumber(phoneNumber, appVerifier);
  3. Reset or even remove recaptcha
    • grecaptcha.reset(window.recaptchaWidgetId);

Above is a rough sequence of the operations that you should follow and I believe you already know how these work.

When your application moves to the second component, you may wish to use the existing implementation (the functions in the first component) by passing the functions as arguments in React. However, this approach creates some trouble for the RecaptchaVerifier, because you already used the recaptcha session to send the first SMS and if your user attempts to send the SMS again, you will need a new recaptcha session. Plus, you will also need a recaptcha container in your second component as well. Recaptcha container is the place that grecaptcha-badge will be loaded in an iframe. In order to avoid these conflicts, I have implemented the same set of methods in the second component as well. And to prevent any other potential conflicts, I created a separate recaptcha-container with a new id.

First component’s container:

<div id=”recaptcha-container” />

Second component’s container:

<div id=”recaptcha-container-resend” />

So that, the user may resend SMS verification several times more as long as RecaptchaVerifier does not believe that the user is a robot 🙂

Other Tips

Always use forms

See the screenshot below from my web application. The user interface is in Norwegian 🇳🇴 🙂

Screenshot 2019-06-16 at 17.49.23
Example User Interface for SMS Verification

We basically have one text box for the phone number and a submit button. So, this has to be implemented as a form, right? The picture below shows a simplified JSX code for this form:

Screenshot 2019-06-16 at 18.06.11

A good practice is to place the recaptcha-container at the bottom of the form. So that, there will be no confusing accessibility issues for the blind people. Also, we initialise the sign in process via this.handleSubmit call. This approach provides an advantage for desktop users, because handleSubmit will allow triggering the recaptcha check by pressing [ENTER] button while the focus is on phoneNumberInput element (<input … />). As a result of these benefits, always use forms while implementing Firebase SMS Verification interface.

Watch out for unknown error states

PhoneAuthProvider gives you a list of error codes, but there is no documentation for all errors. (See documentation here.) One of these obscure errors is auth/code-expired. This error is triggered when the user enters the wrong SMS code three consecutive times.

Recaptcha window is not responsive

This is another unfortunate case with Firebase Recaptcha services. Captcha pictures presented inside the iframe have fixed width and critical recaptcha buttons become invisible and non-scrollable for the users with very small mobile screens (such as iPhone5). To fix this issue, I recommend using some media query on grecaptcha-badge CSS class. See the code below:

Screenshot 2019-06-16 at 18.16.29
Media query for

The result is not perfect, but it keeps the iPhone 5 users in the game.

IMG_1793

Use libphonenumber-js for formatting

If you’d like to format the phone number inside the text box (<input className=”phoneNumberInput” … />), libphonenumber-js is a great utility. You can apply required country code settings by simply adding 3 lines of code into your application. You can learn more about AsYouType formatter by the URL below:

https://www.npmjs.com/package/libphonenumber-js

Credits to my colleague Iva Ivanova 👩‍🔧 on this final tip.

That’s all folks! See you next time with another challenge!

Sercan Leylek / OSLO

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s