How to automatically read SMS in Ionic 5 apps
In this post, we will learn how to read SMS in an Ionic app automatically. Reading SMS is a popular feature found in the majority of popular apps today. Mostly, this is used for automatic approval of OTP in authentication or online payment processes.
Traditionally SMS were read by SMS after asking for READ_SMS
permission, but that has changed since the introduction of Retriever API from Google. More on that in further sections (Step 2).
What is Ionic 5?
You probably already know about Ionic, but I’m putting it here just for the sake of beginners. Ionic is a complete open-source SDK for hybrid mobile app development. Ionic provides tools and services for developing hybrid mobile apps using Web technologies like CSS, HTML5, and Sass.
So, in other words — If you create Native apps in Android — you code in Java. If you create Native apps in iOS — you code in Obj-C or Swift. Both of these are powerful but complex languages. With Ionic and Cordova/Capacitor you can write a single piece of code for your app that can run on both iOS and Android (and windows!), that too with the simplicity of HTML, CSS, and JS.
Why receive SMS automatically?
Apps can communicate in a number of ways. Most apps receive information from servers using push notifications. Push notification information can be easily processed by the apps automatically. (You can read my detailed blog on how to include push notifications in an Ionic 5 app)
But on occasions, you get information via a third party service which can be delivered effectively only using SMS. For example, when making a credit card payment, you receive an SMS containing the OTP (one-time password) for the transaction. Modern apps automatically read the SMS and capture the OTP, and complete the transaction process. This brings in a huge UX boost, where the user doesn’t have to interact with the app for a long time to make the payment.
Another example is the Login / authentication process. Apps which are mobile number centric, mostly allow users to register with their phone number. To validate if the user has the phone number he/she claims the app server sends an OTP, and the app can verify the OTP automatically to register the user, something like this :
Structure
We are going to build a small Ionic 5 app with the SMS reading feature. Following are the steps we’ll take
- Step 1 — Create a sample Ionic 5 app with dummy registration flow
- Step 2 — App hash and retriever API
- Step 3— Implement the Cordova plugin to read SMS
- Step 4— Build the app on android device
- Step 5— Test automatic SMS read to approve a sample registration
Let’s dive right in
Step 1 — Create a sample Ionic 5 app
I have covered this topic in detail in this blog.
In short, the steps you need to take here are
- Make sure you have node installed in the system (V14.x at the time of this blog post)
- Install ionic cli using npm (mine is Ionic 5.5 and NPM 7.x at the time of this post)
- Create an Ionic app using
ionic start
You can create a blank
starter for the sake of this tutorial. On running ionic start appName blank
, node modules will be installed. Once the installation is done, run your app on browser using
$ ionic serve
Here is how the app will look like.
The UI is pretty simple for a registration screen. Here’s the flow
- The user enters the email and password and clicks “Next”
- OTP input shows up. At this point, your server should send an SMS to this number. We will simulate this by sending SMS from another phone to our app build device. In a real-world scenario — you can use services like Twilio or Firebase phone authentication to generate the SMS during the auth process.
- The app reads the SMS and fills it up in the OTP input. If in a real scenario, OTP is not automatically read, the user can always input it manually. But for demo purpose, we’ll keep the OTP input read-only
- Once OTP is received, you can proceed to “Register”
I leave the UI (HTML + CSS) on you, you can make it anyway you like.
Step 2 — App Hash and Retriever API
Before setting up the plugin, let’s learn a little about App Hash and SMS retriever API.
Early android apps used a READ_SMS
permission which allowed the app to read ALL SMS from your device. In 2020, Google released the SMS Retriever API that allows you to fetch the SMS without any permission from the app. That means you don’t have to give the app “Read SMS” permission, thereby avoiding any privacy issues. In fact, READ_SMS
permission can now get your app rejected from app store, as this comes under Dangerous permission category. Hence the old plugins which used READ_SMS
permission are now effectively deprecated.
The SMS Retriever APIhelps in reading SMS without permission. It reads SMS based on App Hash — An 11 digit unique hash string used for auto verifying SMS. Google Play Services utilizes the hash string to figure out which messages to send to your application.
This unique hash can be different for different environments. For example, if an app is signed by a debug keystore for development the hash will be different from production build or if the app is signed by Google Play.
Reading SMS with App Hash
To read SMS using retriever API, we should know the SMS syntax which the API can read correctly. A valid verification message might look like the following:
Your OTP is: 672838 /kkeid8sksd3
The last 11 digits alphanumeric character is the unique hash generated for the app. That 11 digits unique character is the main key which google play services reads for the SMS using the SMS Retriever API. So basically, you’ll need the App Hash on the server side, to be sent along with the SMS.
Generating App Hash
Google has given exact instruction for generating Key hash on this link. I will discuss this in short here.
For debug or production keystore, you can just use this command
$ keytool -exportcert -alias <<KEYSTORE_ALIAS>> -keystore <<KEYSTORE_PATH>>| xxd -p | tr -d "[:space:]" | echo -n <<APP_PACKAGE_NAME>>`cat` | sha256sum | tr -d "[:space:]-" | xxd -r -p | base64 | cut -c1-11
// output - uv+otVdzZzc <-- App Hash
Where, app_package_name is the bundle_ID, which looks like com.enappd.readsms
. If you use app signing by Google Play, follow this link for additional information.
Note — Do not make your app hash public
Now, we are ready to setup the plugins and implement SMS read feature in our app.
Step 3— Implement the Cordova plugin to read SMS
For reading SMS via the Ionic 5 app, there are few plugins available.
- cordova-plugin-sms-receive (super-ceded by retriever) — The trouble with this plugin was that it asks for
SMS_READ
permission in the app. Hence it is NOT recommended to use in production apps, your app might even get rejected from app store with this plugin.
If you still want to use this plugin, you can check the implementation on this blog — Read SMS in Ionic apps - cordova-plugin-sms-retriever
- ionic-native-sms-retriever-plugin-master (Recommended by Ionic) — No
SMS_READ
permission required. The app recognizes the SMS meant for it usingAPP_HASH
We will implement the Ionic recommended plugin, but other plugins can work in your app as well.
To install the plugin, run
$ ionic cordova plugin add cordova-plugin-sms-retriever-manager $ npm install @ionic-native/sms-retriever
Import the plugin in app.module.ts
and add to providers array
import { SmsRetriever } from '@ionic-native/sms-retriever/ngx';
@NgModule({
... ,
providers: [SmsRetriever, { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
...
})
export class AppModule { }
Page flow
As the app starts, it redirects to Login
page. Once the OTP is approved, you redirect to Home
page. The app-routing.module.ts
routes
object looks like below
const routes: Routes = [ { path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomePageModule) },
{ path: 'login', loadChildren: () => import('./login/login.module').then(m => m.LoginPageModule) },
{ path: '', redirectTo: 'login', pathMatch: 'full' }];
OTP Flow
Import the plugin in your login.page.ts
using
import { SmsRetriever } from '@ionic-native/sms-retriever';
Now, there are two methods available with the plugin
- getAppHash — Returns a promise that resolves when successfully generate hash of APP.
this.smsRetriever.getAppHash() .then((res: any) => console.log(res)) .catch((error: any) => console.error(error))
This function gives the same App Hash as we generated in previous section.
- startWatching —Returns a promise that resolves when retrieves SMS text or Times out after 5 min.
this.smsRetriever.startWatching() .then((res: any) => console.log(res)) .catch((error: any) => console.error(error));
Overall, our login.page.ts
looks like this
Step 4— Build an app on android device
If you have carried out the above steps correctly, the Android build should be a breeze. Run the following command to create an Android platform
$ ionic cordova platform add android
Once platform is added, run the app on device (Make sure you have a device attached to the system). You’ll need an actual SIM connection to receive SMS
$ ionic cordova run android
Once your app is up and running on the device, we’ll send SMS from another device simulating a server behavior, or use any other application to send SMS to your phone.
Step 5— Test automatic SMS reading to approve a sample registration
In case you missed it in Step 1, here are the steps again.
- The user enters the Email and password and clicks “Next”
- OTP input shows up
- At this point, send an SMS from another device to your build device
- The app reads the SMS and fills it up in the OTP input
- Once OTP is received, you can proceed to “Register”
The complete process will appear something as given in the below GIF
Watch how the SMS is automatically read so quickly, even before the notification of the SMS even popped from the top.
Conclusion
In this blog, you learned how to implement automatic SMS reading in an Ionic 5 app using SMS retrieve API. This API is safe in usage as it only reads the SMS meant for your particular app, using the App Hash.
Automatic SMS reading is useful in modules like automatic OTP reading for authentication or automatic OTP reading for online transactions.
That’s all for this blog. This was quite a read, but a very interesting feature for your next Pro app.
Stay tuned for more Ionic blogs !