Firebase Push Notification in Ionic React app using Capacitor
Tags: ionic, react, firebase, pushnotification
Published: 2020-03-28 12:20:44

<main role="main"><article class=" u-minHeight100vhOffset65 u-overflowHidden postArticle postArticle--full is-supplementalPostContentLoaded is-withAccentColors" lang="en"><div class="postArticle-content js-postField js-notesSource editable" id="editor_6" g_editable="true" role="textbox" contenteditable="true" data-default-value="Title
Tell your story…" spellcheck="false"><section name="747f" class="section section--body section--first"><div class="section-divider"><hr class="section-divider"></div><div class="section-content"><div class="section-inner sectionLayout--insetColumn"><p name="5439" class="graf graf--p graf-after--figure">This post is for Ionic React framework,<a href="https://enappd.com/blog/camera-and-gallery-in-ionic-react-app-using-capacitor/110/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank"> </a>using Capacitor. In this post you’ll learn how to implement push notifications in Ionic-React apps, using Firebase. First, I’ll cover this feature for Android apps, will update the blog with iOS implementation soon.</p><p name="44db" class="graf graf--p graf-after--p">If you are looking for Push notification functionality in</p><ul class="postList"><li name="8252" class="graf graf--li graf-after--p is-selected">Ionic Angular app&#8202;—&#8202;Please check <a href="https://enappd.com/blog/implement-ionic-4-firebase-push/34"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">this blog</a></li><li name="4076" class="graf graf--li graf-after--li">React Native app&#8202;—&#8202;Please check <a href="https://enappd.com/blog/firebase-push-notifications-in-react-native/81"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">this blog</a></li><li name="4a8c" class="graf graf--li graf-after--li">Ionic React app / Capacitor app&#8202;—&#8202;Continue reading 😄</li></ul><p name="5a29" class="graf graf--p graf-after--li">As you can see from above, there are several options available for Hybrid app development these days, and it is easy to get confused between them. This post is focussed on <strong class="markup--strong markup--p-strong">Ionic framework</strong> with <a href="https://reactjs.org/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--p-strong">React</strong></a> as the front-end framework, and <a href="https://capacitor.ionicframework.com/docs/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--p-strong">Capacitor</strong></a> as runtime and build environment.</p><blockquote name="f294" class="graf graf--blockquote graf-after--p"><strong class="markup--strong markup--blockquote-strong">Code for this tutorial is available on Github repo </strong><a href="https://github.com/enappd/ionic-react-push"  class="markup--anchor markup--blockquote-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--blockquote-strong">ionic-react-push</strong></a></blockquote><p name="8baa" class="graf graf--p graf-after--blockquote">Let’s see a brief intro to each of the included frameworks:</p><ol class="postList"><li name="0ad7" class="graf graf--li graf-after--p">Ionic</li><li name="71d0" class="graf graf--li graf-after--li">Capacitor</li><li name="f282" class="graf graf--li graf-after--li">Ionic-React</li><li name="e728" class="graf graf--li graf-after--li">Firebase</li></ol><h3 name="244d" class="graf graf--h3 graf-after--li">What is Ionic&nbsp;?</h3><p name="941f" class="graf graf--p graf-after--h3">You probably already know about Ionic, but I’m putting it here just for the sake of beginners. <strong class="markup--strong markup--p-strong">Ionic</strong> is a hybrid mobile app development SDK. It provides tools and services for developing hybrid mobile apps using Web technologies like CSS, HTML5, and Sass. Apps can be built with these Web technologies and then distributed through native app stores to be installed on devices by leveraging <a href="https://cordova.apache.org/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Cordova</a> environment.</p><p name="010c" class="graf graf--p graf-after--p">So, in other words&#8202;—&#8202;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. <strong class="markup--strong markup--p-strong">With Cordova (and Ionic) you can write a single piece of code for your app that can run on both iOS and Android </strong>(and windows!), that too with the simplicity of HTML, CSS, and JS.</p><p name="0f04" class="graf graf--p graf-after--p">It is important to note the contribution of Cordova in this. Ionic is only a UI wrapper made up of HTML, CSS and JS. So, by default, Ionic cannot run as an app in an iOS or Android device. Cordova is the build environment that containerizes (sort of) this Ionic web app and converts it into a device installable app, along with providing this app access to native APIs like Camera etc.</p><h3 name="a431" class="graf graf--h3 graf-after--p">What is Capacitor&nbsp;?</h3><p name="8090" class="graf graf--p graf-after--h3">Cordova helps build Ionic web app into a device installable app. But there are some limitations of Cordova, which Capacitor tries to overcome with a new App workflow.</p><p name="f84c" class="graf graf--p graf-after--p">Capacitor is a cross-platform app runtime that makes it easy to build web apps that run natively on iOS, Android, Electron, <em class="markup--em markup--p-em">and</em> the web. Ionic people call these apps “Native Progressive Web Apps” and they represent the next evolution beyond Hybrid apps.</p><blockquote name="6299" class="graf graf--blockquote graf-after--p"><strong class="markup--strong markup--blockquote-strong">Capacitor is very similar to Cordova, but with some key differences in the app workflow</strong></blockquote><p name="e43f" class="graf graf--p graf-after--blockquote">Here are the differences between Cordova and Capacitor</p><ol class="postList"><li name="21a5" class="graf graf--li graf-after--p">Capacitor considers each platform project a <em class="markup--em markup--li-em">source asset</em> instead of a <em class="markup--em markup--li-em">build time asset</em>. That means, Capacitor wants you to keep the platform source code in the repository, unlike Cordova which always assumes that you will generate the platform code on build time</li><li name="68ee" class="graf graf--li graf-after--li">Because of the above, Capacitor does not use <code class="markup--code markup--li-code">config.xml</code> or a similar custom configuration for platform settings. Instead, configuration changes are made by editing <code class="markup--code markup--li-code">AndroidManifest.xml</code> for Android and <code class="markup--code markup--li-code">Info.plist</code> for Xcode</li><li name="d63a" class="graf graf--li graf-after--li">Capacitor does not “run on device” or emulate through the command line. Instead, such operations occur through the platform-specific IDE. So you cannot run an Ionic-capacitor app using a command like <code class="markup--code markup--li-code">ionic run ios</code>&nbsp;. You will have to run iOS apps using Xcode, and Android apps using Android studio</li><li name="3ecd" class="graf graf--li graf-after--li">Since platform code is not a <em class="markup--em markup--li-em">source asset, </em>you can directly change the native code using Xcode or Android Studio. This give more flexibility to developers</li></ol><p name="752e" class="graf graf--p graf-after--li">In essence, Capacitor is like a fresh, more flexible version of Corodva.</p><h4 name="cf20" class="graf graf--h4 graf-after--p">Plugins</h4><p name="dc8c" class="graf graf--p graf-after--h4">Cordova and <a href="https://ionicframework.com/docs/native"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Ionic Native</a> plugins can be used in Capacitor environment. However, there are certain Cordova plugins which are known to be <a href="https://capacitor.ionicframework.com/docs/cordova/known-incompatible-plugins/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">incompatible with Capacitor.</a></p><p name="2367" class="graf graf--p graf-after--p">Other than that, Capacitor also doesn’t support plugin installation with variables. Those changes have to be done manually in the native code.</p><h3 name="1e45" class="graf graf--h3 graf-after--p">Why Ionic React&nbsp;?</h3><p name="25fb" class="graf graf--p graf-after--h3">(Read carefully)</p><p name="0084" class="graf graf--p graf-after--p">Since Ionic 4, Ionic has become framework agnostic. Now you can create Ionic apps in Angular, React, Vue or even in plain JS. This gives Ionic great flexibility to be used by all kinds of developers.</p><p name="4218" class="graf graf--p graf-after--p">It is important to note that <strong class="markup--strong markup--p-strong">Ionic React apps are only supported by Capacitor build environment.</strong></p><p name="4889" class="graf graf--p graf-after--p">Same is not true for Ionic Angular apps<strong class="markup--strong markup--p-strong">&#8202;—&#8202;Ionic Angular apps are supported by both Cordova and Capacitor build environments.</strong></p><p name="a16a" class="graf graf--p graf-after--p">Hence, if you want to build apps in Ionic React, you need to use Capacitor to build the app on device.</p><p name="8640" class="graf graf--p graf-after--p">To build push notification functionality, you can either opt to</p><ul class="postList"><li name="efb1" class="graf graf--li graf-after--p">Install a Cordova plugin for Push (I haven’t tried this yet, but I will), or</li><li name="a06d" class="graf graf--li graf-after--li">Use Capacitor core push functionality</li></ul><p name="21bd" class="graf graf--p graf-after--li">But since we are using Ionic-<strong class="markup--strong markup--p-strong">React, </strong>we need to stick to Capacitor.</p><p name="97da" class="graf graf--p graf-after--p">I know if can get confusing as 4 frameworks are crossing their paths here. <strong class="markup--strong markup--p-strong">Bottom line for this post&#8202;—&#8202;Ionic + React + Capacitor + Firebase Push (using Capacitor core functionality, no Cordova)</strong></p><h3 name="dc0e" class="graf graf--h3 graf-after--p">Firebase</h3><p name="01f0" class="graf graf--p graf-after--h3">Firebase is a Backend-as-a-Service (BaaS) platform. It started as a <a href="http://blog.ycombinator.com/firebase-yc-s11-raises-5-dollars-dot-6m-series-a-from-union-square-ventures-and-flybridge"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">YC11 startup</a> and grew up into a next-generation app-development platform on Google Cloud Platform. It is getting popular by the day because of the ease of integration and variety of functionalities available on it.</p><p name="ffb1" class="graf graf--p graf-after--p">Some of the quick integrations available with Firebase are</p><ul class="postList"><li name="ea04" class="graf graf--li graf-after--p">Email Authentication</li><li name="9a39" class="graf graf--li graf-after--li">Social logins</li><li name="3453" class="graf graf--li graf-after--li">Real-time database</li><li name="196a" class="graf graf--li graf-after--li">Analytics</li><li name="c42f" class="graf graf--li graf-after--li">Crashlytics</li><li name="3f0f" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">Push notifications ⬅️</strong></li><li name="fe08" class="graf graf--li graf-after--li">In-app messages</li><li name="a7e6" class="graf graf--li graf-after--li">Remote config</li></ul><p name="074f" class="graf graf--p graf-after--li">and much more. Firebase is quickly growing to become the most popular mobile app back-end platform.</p><p name="b728" class="graf graf--p graf-after--p">Enough of story-telling, let’s dive into&#8202;—&#8202;How to implement Push notification in Ionic-React apps</p><h3 name="6d48" class="graf graf--h3 graf-after--p">Structure of&nbsp;post</h3><p name="4d40" class="graf graf--p graf-after--h3">I will go step-by-step so everyone can benefit</p><ol class="postList"><li name="aeec" class="graf graf--li graf-after--p">Create a Firebase project</li><li name="efc8" class="graf graf--li graf-after--li">Create a basic Ionic-react app and connect to Firebase</li><li name="929f" class="graf graf--li graf-after--li">Attach Capacitor to your Ionic-react app</li><li name="f76c" class="graf graf--li graf-after--li">Implement Capacitor Push Notification functionality</li><li name="b1b4" class="graf graf--li graf-after--li">Build app on Android, and Test</li></ol><p name="1d41" class="graf graf--p graf-after--li">Let’s get started with Ionic React Push Notification app&nbsp;!</p><h3 name="5edc" class="graf graf--h3 graf-after--p">Step 1&#8202;—&#8202;Create a Firebase project and find Push&nbsp;options</h3><p name="be22" class="graf graf--p graf-after--h3">Go to <a href="https://console.firebase.google.com/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Firebase</a> and create your first project (or use an existing one). Your console should look like this</p><figure tabindex="0" contenteditable="false" name="f144" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 312px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 44.6%;"></div><img class="graf-image" data-image-id="1*Q1tzpM83Uq66TNZ9E28nYA.png" data-width="800" data-height="357" alt="Your Firebase projects all in one place" src="https://cdn-images-1.medium.com/max/800/1*Q1tzpM83Uq66TNZ9E28nYA.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Your Firebase projects all in one&nbsp;place</figcaption></figure><p name="0358" class="graf graf--p graf-after--figure"><strong class="markup--strong markup--p-strong">Note</strong>&#8202;—&#8202;It’s really easy to create a Firebase project, but if you still face any issue, follow step 1–4 of <a href="https://enappd.com/blog/how-to-integrate-firebase-in-ionic-4-apps/23/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">this blog</a></p><p name="8711" class="graf graf--p graf-after--p">Click on your project and you’ll enter the project’s dashboard. Look for <strong class="markup--strong markup--p-strong">Cloud Messaging</strong> tab. This is where the magic will happen&nbsp;!</p><figure tabindex="0" contenteditable="false" name="b5d9" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 387px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 55.300000000000004%;"></div><img class="graf-image" data-image-id="1*BBLOAdiHBI_PngzQdVS-BQ.png" data-width="1388" data-height="768" alt="Cloud messaging section of Firebase console&#8202;—&#8202;You can send push notifications from here" src="https://cdn-images-1.medium.com/max/800/1*BBLOAdiHBI_PngzQdVS-BQ.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Cloud messaging section of Firebase console&#8202;—&#8202;You can send push notifications from&nbsp;here</figcaption></figure><h4 name="9722" class="graf graf--h4 graf-after--figure">Create Android app in&nbsp;Firebase</h4><p name="0c48" class="graf graf--p graf-after--h4">For setting up options, you’ll first have to create an Android app in Firebase console. During the process, it will ask you to enter app’s <strong class="markup--strong markup--p-strong">package name</strong> and provide <strong class="markup--strong markup--p-strong">google-services.json.</strong></p><blockquote name="b7ac" class="graf graf--blockquote graf-after--p">Make sure you keep the package name same as what you are setting in ID of your Capacitor app</blockquote><figure tabindex="0" contenteditable="false" name="ac2a" class="graf graf--figure graf-after--blockquote"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 350px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 50%;"></div><img class="graf-image" data-image-id="1*rtd51fTn_frvjGxUEkhiow.png" data-width="1390" data-height="695" alt="Download google-services.json" src="https://cdn-images-1.medium.com/max/800/1*rtd51fTn_frvjGxUEkhiow.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Download google-services.json</figcaption></figure><h3 name="5313" class="graf graf--h3 graf-after--figure">Step 2— Create a basic Ionic-React app</h3><p name="9e7a" class="graf graf--p graf-after--h3">First you need to make sure you have the latest Ionic CLI. This will ensure you are using everything latest (Duh&nbsp;! )&nbsp;. Ensure latest Ionic CLI installation using</p><pre name="cf8a" class="graf graf--pre graf-after--p">$ <code class="markup--code markup--pre-code">npm install -g ionic@latest</code></pre><p name="f38b" class="graf graf--p graf-after--pre">Creating a basic Ionic-React app is not much different or difficult from creating a basic Ionic-Angular app. Start a basic <code class="markup--code markup--p-code">blank</code> starter using</p><pre name="d448" class="graf graf--pre graf-after--p">$ <code class="markup--code markup--pre-code">ionic start IonicReactPush blank --type=react</code></pre><p name="39bc" class="graf graf--p graf-after--pre">You see what just happened. The <code class="markup--code markup--p-code">--type=react</code> told the CLI to create a <strong class="markup--strong markup--p-strong">React</strong> app, not an <strong class="markup--strong markup--p-strong">Angular</strong> app&nbsp;!!</p><p name="8b9b" class="graf graf--p graf-after--p">Run the app in browser using (yes you guessed it right)</p><pre name="96ce" class="graf graf--pre graf-after--p">$ ionic serve</pre><p name="6306" class="graf graf--p graf-after--pre">You won’t see much in the homepage created in the starter. Let’s modify this page to include a button and a list to contain our push notifications</p><figure tabindex="0" contenteditable="false" name="6f58" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 384px; max-height: 676px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 176%;"></div><img class="graf-image" data-image-id="1*VK57ZJGB-8Y0MrKSeOmO4w.png" data-width="384" data-height="676" alt="Home page of ionic-react push notification starter" src="https://cdn-images-1.medium.com/max/800/1*VK57ZJGB-8Y0MrKSeOmO4w.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Home page of ionic-react push notification starter</figcaption></figure><p name="8472" class="graf graf--p graf-after--figure">The code for this layout isn’t very complex</p><figure tabindex="0" contenteditable="false" name="2de5" class="graf graf--figure graf--iframe graf-after--p"><div class="aspectRatioPlaceholder is-locked"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 35.699999999999996%;"></div><div class="iframeContainer">{% gist https://gist.github.com/enappd/dea4720cd69bc343c383fd1e4c3ca82f.js %}</div></div><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for embed (optional)">Code for Home Page layout&#8202;—&#8202;Ionic-react push notification starter</figcaption></figure><h3 name="35d2" class="graf graf--h3 graf-after--figure">Step 3— Attach Capacitor to your Ionic-React app</h3><p name="4384" class="graf graf--p graf-after--h3">Capacitor can be attached to an existing Ionic app as well. To attach Capacitor to your existing Ionic app, run</p><pre name="e29e" class="graf graf--pre graf-after--p">$ <code class="markup--code markup--pre-code">ionic integrations enable capacitor</code></pre><p name="2503" class="graf graf--p graf-after--pre">This will attach Capacitor to your Ionic app. After this, you have to <code class="markup--code markup--p-code">init</code> the Capacitor app with</p><pre name="c8ac" class="graf graf--pre graf-after--p">$ npx cap init</pre><p name="c9af" class="graf graf--p graf-after--pre">It will ask you the app name and ID. Give app name whatever you want. App ID is the domain identifier of your app (ex: <code class="markup--code markup--p-code">com.example.app</code>). Note, this ID should be exactly same as the one you provided in Firebase project (case-sensitive).</p><h4 name="8a27" class="graf graf--h4 graf-after--p">Add google-services.json</h4><p name="ede3" class="graf graf--p graf-after--h4">Add the downloaded <code class="markup--code markup--p-code">google-services.json</code> to your project in <code class="markup--code markup--p-code">android/app</code> folder</p><figure tabindex="0" contenteditable="false" name="7302" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 307px; max-height: 380px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 123.8%;"></div><img class="graf-image" data-image-id="1*HNZraboFVoK5wLnoXu4y5A.png" data-width="307" data-height="380" alt="Add google-services.json in your ionic-react capacitor project" src="https://cdn-images-1.medium.com/max/800/1*HNZraboFVoK5wLnoXu4y5A.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Add google-services.json in your ionic-react capacitor project</figcaption></figure><h4 name="a20f" class="graf graf--h4 graf-after--figure">Configure gradle&nbsp;files</h4><p name="84ad" class="graf graf--p graf-after--h4">Make sure your gradle files are appropriately configured.</p><p name="2c2b" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Project build.gradle </strong>should have <code class="markup--code markup--p-code">google-services</code> and <code class="markup--code markup--p-code">gradle</code> in dependencies</p><pre name="31d1" class="graf graf--pre graf-after--p">dependencies {</pre><pre name="54b0" class="graf graf--pre graf-after--pre">classpath 'com.android.tools.build:gradle:3.3.2'<br>classpath 'com.google.gms:google-services:4.3.2'</pre><pre name="0f07" class="graf graf--pre graf-after--pre">}</pre><p name="b783" class="graf graf--p graf-after--pre"><strong class="markup--strong markup--p-strong">App build.gradle </strong>should have</p><pre name="dc5b" class="graf graf--pre graf-after--p">// On the top<br>apply plugin: 'com.android.application'</pre><pre name="875a" class="graf graf--pre graf-after--pre">// At the bottom of the file<br>apply plugin: 'com.google.gms.google-services'</pre><h3 name="1f20" class="graf graf--h3 graf-after--pre">Step 4— Implement Capacitor Push functionality</h3><p name="7f75" class="graf graf--p graf-after--h3">Capacitor has in-built Push notification capability. Import Push in your app/page with this</p><pre name="8828" class="graf graf--pre graf-after--p">import { Plugins, PushNotification, PushNotificationToken, PushNotificationActionPerformed } from '@capacitor/core';</pre><pre name="a4c4" class="graf graf--pre graf-after--pre">const { PushNotifications } = Plugins;</pre><p name="28a4" class="graf graf--p graf-after--pre">There are few plugins in-built in <code class="markup--code markup--p-code">Capacitor/core</code>&nbsp;. You can access these by simply importing.</p><p name="40b7" class="graf graf--p graf-after--p">There are four important listeners and one function for Push functionality</p><h4 name="9569" class="graf graf--h4 graf-after--p">Register function</h4><p name="d7e6" class="graf graf--p graf-after--h4">Register function registers your device on FCM server. In response, you receive a <code class="markup--code markup--p-code">token</code>&nbsp;. FCM uses this token to identify your device. That’s how you can pin point a device to send push notifications. You can register simply by</p><pre name="4643" class="graf graf--pre graf-after--p">PushNotifications.register();</pre><h4 name="6742" class="graf graf--h4 graf-after--pre">Listeners</h4><ol class="postList"><li name="6082" class="graf graf--li graf-after--h4"><strong class="markup--strong markup--li-strong">registration</strong>&#8202;—&#8202;This listeners will fire when your token registration is successful. You receive the <code class="markup--code markup--li-code">token</code> in the response as well</li><li name="14e1" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">registrationError</strong>&#8202;—&#8202;This listener will fire when your registration is not successful. Without a successful registration you won’t receive push on the device. If this happens, you can ask user to try to register again</li><li name="1766" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">pushNotificationReceived</strong>&#8202;—&#8202;This listener is very important, as it fires when you receive the notification when the app is open (in foreground). The listener provides you the notification payload which you can use to show message to user</li><li name="a2ea" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">pushNotificationActionPerformed</strong>&#8202;—&#8202;This listener is also very important, as it fires when you tap the notification received when the app is closed or in background.&nbsp;<br>The listener provides you the data payload which you can use to show message to user, but the payload is a little different from the <code class="markup--code markup--li-code">pushNotificationReceived</code><strong class="markup--strong markup--li-strong"> </strong>listener. You have to send useful information in <code class="markup--code markup--li-code">data</code> field of the notification to receive it in this listener. <code class="markup--code markup--li-code">title</code> and <code class="markup--code markup--li-code">body</code> fields are not received in this payload</li></ol><p name="fe5b" class="graf graf--p graf-after--li">Complete implementation of all this will look like the following (omitting layout code here)</p><figure tabindex="0" contenteditable="false" name="4f96" class="graf graf--figure graf--iframe graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 35.699999999999996%;"></div><div class="iframeContainer">{% gist https://gist.github.com/enappd/b36ecc2951d7f52f1980e3d00a87acb3.js %}</div></div></figure><p name="c598" class="graf graf--p graf-after--figure">I will attach the <code class="markup--code markup--p-code">push()</code> function on<code class="markup--code markup--p-code">onClick</code> event of the footer button, so we register on demand (simulating a situation where you ask user whether they want to receive notifications)</p><pre name="c264" class="graf graf--pre graf-after--p">&lt;IonButton expand="full" onClick={() =&gt; this.push()}&gt;Register for Push&lt;/IonButton&gt;</pre><p name="32cc" class="graf graf--p graf-after--pre">That’s it&nbsp;! Push notifications are integrated&nbsp;! Now all we gotta do is&nbsp;… test 😑</p><h3 name="29f7" class="graf graf--h3 graf-after--p">Step 5— Build app on Android, and&nbsp;test</h3><p name="34b9" class="graf graf--p graf-after--h3">Before adding a platform to Capacitor, you need to <em class="markup--em markup--p-em">build</em> the app once. Build the app using</p><pre name="4d03" class="graf graf--pre graf-after--p"><code class="markup--code markup--pre-code">$ ionic build</code></pre><p name="ccd4" class="graf graf--p graf-after--pre">Now add Android platform (or iOS)</p><pre name="b984" class="graf graf--pre graf-after--p">$ npx cap add android</pre><p name="d07b" class="graf graf--p graf-after--pre graf--trailing">This should add Android platform to your project.</p></div></div></section><section name="828a" class="section section--body"><div class="section-divider"><hr class="section-divider"></div><div class="section-content"><div class="section-inner sectionLayout--insetColumn"><h4 name="518f" class="graf graf--h4 graf--leading">Troubleshoot Tip</h4><p name="3f6b" class="graf graf--p graf-after--h4">If you face an error saying</p><pre name="a611" class="graf graf--pre graf-after--p">Capacitor could not find the web assets directory "/Users/abhijeetrathore/ionic-4-music/www".</pre><p name="88c3" class="graf graf--p graf-after--pre graf--trailing">Check your <code class="markup--code markup--p-code">capacitor.config.json</code> file. Make sure the <code class="markup--code markup--p-code">webDir</code> field has a value of <code class="markup--code markup--p-code">www</code>&nbsp;. If not, change the <code class="markup--code markup--p-code">webDir</code> field to have the same value as the last parameter of the url showing up in the above error</p></div></div></section><section name="ecd8" class="section section--body section--last"><div class="section-divider"><hr class="section-divider"></div><div class="section-content"><div class="section-inner sectionLayout--insetColumn"><p name="6fce" class="graf graf--p graf--leading">Note, you cannot run the project directly on the phone using CLI in Capacitor. You will have to open the project in Android Studio and run using the Android Studio IDE. Open the project in Android Studio using</p><pre name="c540" class="graf graf--pre graf-after--p"><code class="markup--code markup--pre-code">$ npx cap open android</code></pre><p name="4db5" class="graf graf--p graf-after--pre">Now run the app in your device using Android Studio, and you get this&nbsp;! (Sample from my One Plus 6T, Android P)</p><blockquote name="152b" class="graf graf--blockquote graf-after--p">Note: After adding a platform, if you make any changes in the app, you need to run <code class="markup--code markup--blockquote-code"><em class="markup--em markup--blockquote-em">ionic build</em></code> and then <code class="markup--code markup--blockquote-code"><em class="markup--em markup--blockquote-em">npx cap sync</em></code> to reflect those changes in the native platform</blockquote><h4 name="2f09" class="graf graf--h4 graf-after--blockquote">Register your device for push notification</h4><p name="b5c6" class="graf graf--p graf-after--h4">Click “Register for push” to register your device for push notifications. I have the token displayed in alert in the <code class="markup--code markup--p-code">registration</code> listener</p><figure tabindex="0" contenteditable="false" name="80ab" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 350px; max-height: 622px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 177.7%;"></div><img class="graf-image" data-image-id="1*hN7dEhp0hl2a0rzwt6GEIw.gif" data-width="350" data-height="622" alt="Register your device for Push notification&#8202;—&#8202;receive token from FCM server" src="https://cdn-images-1.medium.com/max/800/1*hN7dEhp0hl2a0rzwt6GEIw.gif"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Register your device for Push notification&#8202;—&#8202;receive token from FCM&nbsp;server</figcaption></figure><h4 name="e667" class="graf graf--h4 graf-after--figure">Send push from Firebase&nbsp;console</h4><p name="4a9d" class="graf graf--p graf-after--h4">To receive a push notification in the app, you will have to&nbsp;…. of course&nbsp;… send a notification first.</p><blockquote name="47c9" class="graf graf--blockquote graf-after--p">I have a detailed tutorial on <a href="https://enappd.com/blog/sending-push-using-firebase-console/35"  class="markup--anchor markup--blockquote-anchor" rel="noopener"    target="_blank">how to send Notifications using Firebase console</a></blockquote><p name="6677" class="graf graf--p graf-after--blockquote">To send a notification, we can use <strong class="markup--strong markup--p-strong">Firebase console → Cloud messaging</strong> section.</p><figure tabindex="0" contenteditable="false" name="880e" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 302px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 43.2%;"></div><img class="graf-image" data-image-id="1*UkgjAc55oFF7wQMeFXkJCg.png" data-width="987" data-height="426" alt="Notification section in Compose form&#8202;—&#8202;Firebase cloud messaging console" src="https://cdn-images-1.medium.com/max/800/1*UkgjAc55oFF7wQMeFXkJCg.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Notification section in Compose form&#8202;—&#8202;Firebase cloud messaging console</figcaption></figure><ul class="postList"><li name="226b" class="graf graf--li graf-after--figure"><strong class="markup--strong markup--li-strong">Notification Title</strong>&#8202;—&#8202;This is the title that shows up in the push message in Android devices. iOS does not show this title on push messages</li><li name="35c8" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">Notification Text&#8202;</strong>—&#8202;This is the main body of the message. This is the text content that users see in the push notification</li></ul><p name="4703" class="graf graf--p graf-after--li">Enter both these info. Now, you have two choice</p><p name="60d0" class="graf graf--p graf-after--p">A. You can send a simple push notification, OR</p><p name="1da0" class="graf graf--p graf-after--p">B. You can send a test push notification using your registration token</p><p name="50fc" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Method B</strong> is very useful when you have a live app, and you don’t want your test push to go to every user. I’ll use this method to stick to development guidelines.</p><h4 name="b217" class="graf graf--h4 graf-after--p"><strong class="markup--strong markup--h4-strong">Sending test push notification&#8202;—&#8202;Method&nbsp;B</strong></h4><p name="2bcf" class="graf graf--p graf-after--h4">Click <strong class="markup--strong markup--p-strong">Send Test Message</strong> in the notification section. You will be presented with the following popup</p><figure tabindex="0" contenteditable="false" name="3c55" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 402px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 57.49999999999999%;"></div><img class="graf-image" data-image-id="1*-xrc8PfpnHGxhne9cFY1mw.png" data-width="764" data-height="439" alt="Enter your device token to send a test push" src="https://cdn-images-1.medium.com/max/800/1*-xrc8PfpnHGxhne9cFY1mw.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Enter your device token to send a test&nbsp;push</figcaption></figure><p name="2913" class="graf graf--p graf-after--figure">You need to find out your device’s <strong class="markup--strong markup--p-strong">device_token </strong>(which you received after registering the device on FCM)<strong class="markup--strong markup--p-strong"> </strong>and enter that here. Click <strong class="markup--strong markup--p-strong">Send</strong> to send a test push notification to ONLY your device. So handy, right?</p><h4 name="1c04" class="graf graf--h4 graf-after--p">Receive a push in Open app (in foreground)</h4><p name="b3ce" class="graf graf--p graf-after--h4">In open app, you’ll receive the push without any notification in the notification tray. I have the notification data attached with the list, so the new notification will show up in the list, but you can always attach an alert in the <code class="markup--code markup--p-code">pushNotificationReceived</code> listener</p><figure tabindex="0" contenteditable="false" name="acb8" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 350px; max-height: 622px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 177.7%;"></div><img class="graf-image" data-image-id="1*r-G6Sd4GH8F8j-P0h3-50g.gif" data-width="350" data-height="622" src="https://cdn-images-1.medium.com/max/800/1*r-G6Sd4GH8F8j-P0h3-50g.gif"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Receive push in Ionic react capacitor app&#8202;—&#8202;Foreground app</figcaption></figure><p name="c752" class="graf graf--p graf-after--figure">I sent three push back to back, just in case you miss one. The data format received in foreground app is like this</p><pre name="be37" class="graf graf--pre graf-after--p">{<br> "id":"0:1569331101047632%008d0b4c008d0b4c",<br> "data":{<br>  "body":"This is my second push",<br>  "title":"Test Push"<br> },<br>  "title":"Test Push",<br>  "body":"This is my third push"<br>}</pre><h4 name="b6cc" class="graf graf--h4 graf-after--pre">Receive a push in Background app (in background)</h4><p name="d19b" class="graf graf--p graf-after--h4">In minimized (background) app, you’ll receive the push with a notification in the notification tray. Once you tap the notification, the app with open, and the <code class="markup--code markup--p-code">pushNotificationActionPerformed</code> listener will be called. You can receive the data from this listener</p><figure tabindex="0" contenteditable="false" name="2465" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 350px; max-height: 622px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 177.7%;"></div><img class="graf-image" data-image-id="1*wtO9HpsZOlO6FFshbRkCKg.gif" data-width="350" data-height="622" alt="Receive push in Ionic react capacitor app&#8202;—&#8202;Background app" src="https://cdn-images-1.medium.com/max/800/1*wtO9HpsZOlO6FFshbRkCKg.gif"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Receive push in Ionic react capacitor app&#8202;—&#8202;Background app</figcaption></figure><p name="4741" class="graf graf--p graf-after--figure">The data format received in background app is like this</p><pre name="b363" class="graf graf--pre graf-after--p">{<br> "actionId":"tap",<br> "notification":{<br>  "id":"0:1569331195228966%008d0b4c008d0b4c",<br>  "data":{<br>   "google.delivered_priority":"high",<br>   "google.sent_time":"1569331195220",<br>   "google.ttl":"2419200",<br>   "google.original_priority":"high",<br>   "body":"This is my second push",<br>   "from":"160012889513",<br>   "title":"Test Push",<br>   "collapse_key":"com.enappd.IonicReactPush"}<br> }<br>}</pre><p name="d4e6" class="graf graf--p graf-after--pre">You can see here that you can access the <code class="markup--code markup--p-code">title</code>&nbsp;, <code class="markup--code markup--p-code">body</code> parameters inside the <code class="markup--code markup--p-code">data</code> field of the payload. This <code class="markup--code markup--p-code">data</code> field can be populated in Firebase console using <strong class="markup--strong markup--p-strong">Additional Options Section</strong></p><figure tabindex="0" contenteditable="false" name="3ddd" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 466px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 66.60000000000001%;"></div><img class="graf-image" data-image-id="1*er20SYLSDnqsYMaw0k1rFg.png" data-width="1125" data-height="749" alt="Implement additional options in your notification campaign" src="https://cdn-images-1.medium.com/max/800/1*er20SYLSDnqsYMaw0k1rFg.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Implement additional options in your notification campaign</figcaption></figure><h4 name="ca4d" class="graf graf--h4 graf-after--figure">Receive a push in closed/killed app</h4><p name="c737" class="graf graf--p graf-after--h4">In a closed app, you’ll receive the push with a notification in the notification tray. Once you tap the notification, the app with open, but no listener will fire on this tap. Probably this feature isn’t yet available in Capacitor.</p><p name="bc88" class="graf graf--p graf-after--p">🎉🎉🎉 Congrats&nbsp;! You just implemented Push notification functionality using Capacitor, in Ionic React App&nbsp;!</p><h3 name="d9c7" class="graf graf--h3 graf-after--p">Conclusion</h3><p name="cf6e" class="graf graf--p graf-after--h3">In this post, you learnt how to implement Push notification functionality in your Ionic React apps using Capacitor. We also tested the functionality on Android device, in an open, minimized and closed app.</p><blockquote name="9738" class="graf graf--blockquote graf-after--p"><strong class="markup--strong markup--blockquote-strong">Code for this tutorial is available on Github repo </strong><a href="https://github.com/enappd/ionic-react-push"  class="markup--anchor markup--blockquote-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--blockquote-strong">ionic-react-push</strong></a></blockquote><p name="c49a" class="graf graf--p graf-after--blockquote">iOS implementation will be updated soon. Happy coding&nbsp;!</p><h3 name="514b" class="graf graf--h3 graf-after--p">Next Steps</h3><p name="d7bd" class="graf graf--p graf-after--h3">Now that you have learned the implementation of Push notification in Ionic React app, you can also try following blogs for <strong class="markup--strong markup--p-strong">Ionic apps</strong></p><h4 name="ae21" class="graf graf--h4 graf-after--p">Ionic React Capacitor</h4><ul class="postList"><li name="38a4" class="graf graf--li graf-after--h4"><a href="https://enappd.com/blog/how-to-make-ionic-apps-in-react-using-capacitor/26"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">How to make basic apps in ionic-react</a>-capacitor</li><li name="e379" class="graf graf--li graf-after--li"><a href="https://enappd.com/blog/camera-and-gallery-in-ionic-react-app-using-capacitor/110"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Camera and Image gallery in Ionic-React-Capacitor</a></li><li name="22af" class="graf graf--li graf-after--li"><a href="https://enappd.com/blog/firebase-push-notification-in-ionic-react-capacitor/111"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Push notification in Ionic-React-Capacitor apps</a></li><li name="af53" class="graf graf--li graf-after--li"><a href="https://enappd.com/blog/play-music-in-ionic-capacitor-apps/112"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Playing Music in Ionic Capacitor apps</a></li><li name="c8de" class="graf graf--li graf-after--li"><a href="https://enappd.com/blog/icon-splash-in-ionic-react-capacitor-apps/114"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Adding Icon and Splash in Ionic React Capacitor apps</a></li><li name="bc1c" class="graf graf--li graf-after--li"><a href="https://enappd.com/blog/facebook-login-in-ionic-react-capacitor-apps/118/"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Facebook login in Capacitor apps&#8202;—&#8202;Ionic React</a></li></ul><p name="e083" class="graf graf--p graf-after--li">If you need a base to start your next <strong class="markup--strong markup--p-strong">Ionic 4 React app</strong>, you can make your next awesome app using <a href="https://store.enappd.com/product/ionic-react-full-app-capacitor/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Ionic React Full App</a></p><figure tabindex="0" contenteditable="false" name="5cfa" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 600px; max-height: 600px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 100%;"></div><img class="graf-image" data-image-id="1*ofk4HAMnl1ZXyArf1TxZjQ.jpeg" data-width="600" data-height="600" alt="Ionic 4 React Full App with huge number of layouts and features" src="https://cdn-images-1.medium.com/max/800/1*ofk4HAMnl1ZXyArf1TxZjQ.jpeg"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Ionic 4 React Full App with huge number of layouts and&nbsp;features</figcaption></figure><h4 name="bd6f" class="graf graf--h4 graf-after--figure">Ionic Angular</h4><ul class="postList"><li name="39ea" class="graf graf--li graf-after--h4">Ionic 4 Payment Gateways&#8202;—&#8202;<a href="https://enappd.com/blog/ionic-4-stripe-payment-integration-with-firebase-for-apps-and-pwa/17"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Stripe</a> | <a href="https://enappd.com/blog/ionic-4-paypal-payment-integration-for-apps-and-pwa/16"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">PayPal</a> | <a href="https://enappd.com/blog/how-to-integrate-apple-pay-in-ionic-4-apps/21"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Apple Pay</a> | <a href="https://enappd.com/blog/how-to-integrate-razorpay-in-ionic-4-apps-and-pwa/20"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">RazorPay</a></li><li name="8665" class="graf graf--li graf-after--li">Ionic 4 Charts with&#8202;—&#8202;<a href="https://enappd.com/blog/ionic-4-charts-using-google-charts/66"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Google Charts </a>| <a href="https://enappd.com/blog/adding-charts-in-ionic-4-apps-and-pwa-part-3/60"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">HighCharts</a> | <a href="https://enappd.com/blog/adding-charts-in-ionic-4-apps-and-pwa-part-2/54"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">d3.js</a> | <a href="https://enappd.com/blog/charts-in-ionic-4-apps-and-pwa-part-1/52"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Chart.js</a></li><li name="fd9c" class="graf graf--li graf-after--li">Ionic 4 Social Logins&#8202;—&#8202;<a href="https://enappd.com/blog/facebook-login-in-ionic-4-apps-using-firebase/25"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Facebook</a> | <a href="https://enappd.com/blog/google-login-in-ionic-4-apps-using-firebase/39"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Google</a> | <a href="https://enappd.com/blog/twitter-login-in-ionic-4-apps-using-firebase/24"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Twitter</a></li><li name="31b6" class="graf graf--li graf-after--li">Ionic 4 Authentications&#8202;—&#8202;<a href="https://enappd.com/blog/email-authentication-with-firebase-in-ionic-4/38"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Via Email</a> | <a href="https://enappd.com/blog/firebase-anonymous-login-in-ionic-4/37"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Anonymous</a></li><li name="4a75" class="graf graf--li graf-after--li">Ionic 4 Features&#8202;—&#8202;<a href="https://enappd.com/blog/using-geolocation-geocoding-and-reverse-geocoding-in-ionic-4/45"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Geolocation</a> | <a href="https://enappd.com/blog/qr-code-scanning-and-optical-character-recognition-ocr-in-ionic-4/9"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">QR Code reader </a>| <a href="https://enappd.com/blog/best-fitness-plugins-for-ionic-4-how-to-use-pedometer/15"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Pedometer</a></li><li name="819d" class="graf graf--li graf-after--li">Media in Ionic 4&#8202;—&#8202;<a href="https://enappd.com/blog/spotify-like-music-in-ionic-4-apps/48"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Audio</a> | <a href="https://enappd.com/blog/adding-video-player-in-ionic-4-app/64"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Video</a> | <a href="https://enappd.com/blog/image-picker-in-ionic-4-app/67"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Image Picker</a> | <a href="https://enappd.com/blog/how-to-add-image-cropper-in-ionic-4-app/68"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Image Cropper</a></li><li name="eee3" class="graf graf--li graf-after--li">Ionic 4 Essentials&#8202;—&#8202;<a href="https://enappd.com/blog/ionic-4-save-and-retrieve-data-locally-on-device/59"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Native Storage</a> | <a href="https://enappd.com/blog/how-to-translate-in-ionic-4-globalization-internationalization-and-localization/11"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Translations</a> | <a href="https://enappd.com/blog/rtl-right-to-left-use-in-ionic-4/50"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">RTL</a></li><li name="8bbe" class="graf graf--li graf-after--li">Ionic 4 messaging&#8202;—&#8202;<a href="https://enappd.com/blog/implement-ionic-4-firebase-push/34"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Firebase Push</a> | <a href="https://enappd.com/blog/automatically-read-sms-in-ionic-4-apps/42"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Reading SMS</a></li><li name="2467" class="graf graf--li graf-after--li">Ionic 4 with Firebase&#8202;—&#8202;<a href="https://enappd.com/blog/how-to-integrate-firebase-in-ionic-4-apps/23"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Basics</a> | <a href="https://enappd.com/blog/firebase-with-ionic-4-hosting-auth-and-db-connection/58"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Hosting and DB</a> | <a href="https://enappd.com/blog/firebase-cloud-functions-in-ionic-4-complete-guide/32"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Cloud functions</a></li></ul><p name="2c47" class="graf graf--p graf-after--li">If you need a base to start your next <strong class="markup--strong markup--p-strong">Ionic 4 Angular app</strong>, you can make your next awesome app using <a href="https://store.enappd.com/product/ionic-4-full-app"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Ionic 4 Full App</a></p><figure tabindex="0" contenteditable="false" name="0c02" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 560px; max-height: 353px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 63%;"></div><img class="graf-image" data-image-id="0*FEEIJR0kJXNBCWUo.jpeg" data-width="560" data-height="353" alt="Ionic 4 Full App with huge number of layouts and features" src="https://cdn-images-1.medium.com/max/800/0*FEEIJR0kJXNBCWUo.jpeg"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Ionic 4 Full App with huge number of layouts and&nbsp;features</figcaption></figure><p name="9181" class="graf graf--p graf--empty graf-after--figure graf--trailing"><br></p></div></div></section></div></article></main>