Facebook login in Capacitor apps with Ionic Angular
Tags: ionic, capacitor, angular, facebook
Published: 2020-03-29 22:19:15

<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="99d5" 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="a5f6" class="graf graf--p graf-after--figure">In this post, you’ll learn how to implement <strong class="markup--strong markup--p-strong">Facebook login</strong> in your Capacitor apps, based on Ionic Angular framework. Following are the outcomes of this blogpost</p><ul class="postList"><li name="f7ec" class="graf graf--li graf-after--p">Login using Facebook in a Capacitor Ionic app (Angular)</li><li name="4738" class="graf graf--li graf-after--li">Retrieve user name and profile photo to show after login</li><li name="381a" class="graf graf--li graf-after--li">Auto-login users after first login</li></ul><h4 name="c47f" class="graf graf--h4 graf-after--li">Disclaimer</h4><p name="c222" class="graf graf--p graf-after--h4 is-selected">Since this post is a mix of three frameworks, it is possible you landed here by mistake. If you are looking for Facebook login in</p><ul class="postList"><li name="f09a" class="graf graf--li graf-after--p">Ionic Angular (Cordova) apps&#8202;—&#8202;Please check <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">this post</a></li><li name="d7a0" class="graf graf--li graf-after--li">Ionic React Capacitor Apps&#8202;—&#8202;Please check <a href="https://medium.com/enappd/facebook-login-in-ionic-react-capacitor-apps-338890e3055e"  class="markup--anchor markup--li-anchor"    target="_blank">this post</a></li><li name="334a" class="graf graf--li graf-after--li">React Native&#8202;—&#8202;Please check <a href="https://enappd.com/blog/facebook-login-in-react-native-apps/89"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">this post</a></li><li name="7149" class="graf graf--li graf-after--li">Ionic Angular (Capacitor) apps&#8202;—&#8202;Continue reading 😎</li></ul><p name="a6f7" 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 <strong class="markup--strong markup--p-strong">Angular</strong> 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="f425" class="graf graf--blockquote graf-after--p"><strong class="markup--strong markup--blockquote-strong"><em class="markup--em markup--blockquote-em">Code for this tutorial is available on Github repo </em></strong><a href="https://github.com/enappd/capacitor-facebook-login"  class="markup--anchor markup--blockquote-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--blockquote-strong"><em class="markup--em markup--blockquote-em">ionic-angular-capacitor-facebook-login</em></strong></a></blockquote><p name="6ec3" 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="430b" class="graf graf--li graf-after--p">Ionic</li><li name="0eb5" class="graf graf--li graf-after--li">Capacitor</li></ol><h3 name="5362" class="graf graf--h3 graf-after--li">What is Ionic&nbsp;?</h3><p name="70df" 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="f59a" 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="a73b" class="graf graf--p graf-after--p">It is important to note the contribution of Cordova/Capacitor 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/Capacitor 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="f7d1" class="graf graf--h3 graf-after--p">Capacitor&#8202;—&#8202;How is it different from Cordova&nbsp;?</h3><p name="a887" class="graf graf--p graf-after--h3">Cordova has been the only choice available for hybrid app developers for quite some time. 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="7f22" 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="ac5c" class="graf graf--blockquote graf-after--p"><strong class="markup--strong markup--blockquote-strong"><em class="markup--em markup--blockquote-em">Capacitor is very similar to Cordova, but with some key differences in the app workflow</em></strong></blockquote><p name="8e52" class="graf graf--p graf-after--blockquote">Here are the differences between Cordova and Capacitor (You’ll appreciate these only if you have been using Cordova earlier, otherwise you can just skip)</p><ol class="postList"><li name="45e4" 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="775f" 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="9140" 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="05c2" 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="c44a" class="graf graf--p graf-after--li">In essence, Capacitor is like a fresh, more flexible version of Corodva.</p><h4 name="fdf5" class="graf graf--h4 graf-after--p">Plugins</h4><p name="3a69" 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> For Facebook login functionality, we’ll use the <a href="https://github.com/rdlabo/capacitor-facebook-login"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Capacitor Facebook login plugin</a></p><p name="2293" 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. We will see it in this post.</p><h3 name="319c" class="graf graf--h3 graf-after--p">Structure of&nbsp;post</h3><p name="1215" class="graf graf--p graf-after--h3">I always go step-by-step for readers of all experience level. If you know certain steps, feel free to skip them</p><p name="0242" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 1:</strong> Create a basic Ionic app with Angular</p><p name="6cff" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 2:</strong> Connect Capacitor with your app</p><p name="afd3" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 3:</strong> Create a Facebook app in Developer console</p><p name="782d" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 4: </strong>Setup Facebook Login Plugin and functions</p><p name="a7c6" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 5: </strong>Build and Test your app on Android</p><p name="151c" class="graf graf--p graf-after--p">Let’s get started with Ionic Angular Capacitor Facebook login&nbsp;!</p><h3 name="a27e" class="graf graf--h3 graf-after--p">Step 1&#8202;—&#8202;Create a basic Ionic&nbsp;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. 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="f2ec" class="graf graf--p graf-after--pre">(My node version at the time of writing the blog is 10.16.0)</p><p name="f38b" class="graf graf--p graf-after--p">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 CapFbLogin blank --type=angular</code></pre><p name="39bc" class="graf graf--p graf-after--pre">The <code class="markup--code markup--p-code">--type=angular</code> told the CLI to create an <strong class="markup--strong markup--p-strong">Angular</strong> app, not a <strong class="markup--strong markup--p-strong">React</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, icon and a title for login. Also, I have created a Homepage, where the user is redirected after successful login. The user profile information in this page comes after login and single API call.</p><figure tabindex="0" contenteditable="false" name="bf4c" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 734px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 104.80000000000001%;"></div><img class="graf-image" data-image-id="1*5jugR1NYMBtZDLyGEuuwyQ.jpeg" data-width="2232" data-height="2340" src="https://cdn-images-1.medium.com/max/800/1*5jugR1NYMBtZDLyGEuuwyQ.jpeg"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Login and Homepage for Ionic Capacitor Facebook Login starter&nbsp;app</figcaption></figure><p name="8472" class="graf graf--p graf-after--figure">The code for this can be found in the attached <a href="https://github.com/enappd/capacitor-facebook-login"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Github repository</a>.</p><h3 name="35d2" class="graf graf--h3 graf-after--p">Step 2&#8202;—&#8202;Attach Capacitor to your Ionic&nbsp;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 as this will be required later when you create app in Facebook developer console.</p><h3 name="ee08" class="graf graf--h3 graf-after--p">Step 3&#8202;—&#8202;Create a Facebook app in Developer console</h3><p name="adfa" class="graf graf--p graf-after--h3">Next, we need to create a new app in Facebook’s developer dashboard. This app is the one that Facebook will use to ask our users for permission, when we try to log them into our Ionic app.</p><p name="fd92" class="graf graf--p graf-after--p">&#8203;Go to <a href="https://developers.facebook.com/apps"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--p-strong">F</strong></a><a href="https://developers.facebook.com/apps"  class="markup--anchor markup--p-anchor" rel="noopener noreferrer noopener noopener noopener noopener noopener"    target="_blank"><strong class="markup--strong markup--p-strong">acebook developer console</strong></a> and create a new app.</p><figure tabindex="0" contenteditable="false" name="8ed7" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 313px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 44.7%;"></div><img class="graf-image" data-image-id="0*25XkXnSODKdAfMqY" data-width="1912" data-height="855" alt="Create new app in Facebook Developer console" src="https://cdn-images-1.medium.com/max/800/0*25XkXnSODKdAfMqY"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Create new app in Facebook Developer console</figcaption></figure><p name="9511" class="graf graf--p graf-after--figure">Once you finish creating the app, go to Facebook app dashboard and pick <strong class="markup--strong markup--p-strong">App Id</strong> from there. It will be required for Facebook login in the Ionic app</p><figure tabindex="0" contenteditable="false" name="f1b5" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 386px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 55.2%;"></div><img class="graf-image" data-image-id="1*U8NisQdjifhqnr3Vg_LnDQ.png" data-width="1386" data-height="765" alt="Pick Facebook App ID from Facebook Developer console" src="https://cdn-images-1.medium.com/max/800/1*U8NisQdjifhqnr3Vg_LnDQ.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Pick Facebook App ID from Facebook Developer console</figcaption></figure><h4 name="e7d6" class="graf graf--h4 graf-after--figure">&zwnj;&zwnj;Add your Platform to&nbsp;Facebook</h4><p name="55ae" class="graf graf--p graf-after--h4">We need to let Facebook know which platforms we’ll be using (<em class="markup--em markup--p-em">if it’s just web, iOS, or Android</em>).</p><p name="7ec6" class="graf graf--p graf-after--p">&zwnj;For sample purpose, let’s add Android and iOS platforms&nbsp;.</p><p name="991d" class="graf graf--p graf-after--p">&zwnj;To add the platform, go ahead inside your Facebook dashboard and click on <strong class="markup--strong markup--p-strong">Settings</strong>, go to the bottom of the page and you’ll see a button that says <strong class="markup--strong markup--p-strong">Add Platform.</strong></p><p name="5428" class="graf graf--p graf-after--p">You’ll see several options for the platforms you’re creating</p><figure tabindex="0" contenteditable="false" name="1dd6" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 213px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 30.5%;"></div><img class="graf-image" data-image-id="0*0VnMWKBszvJ5iwCf" data-width="1041" data-height="317" src="https://cdn-images-1.medium.com/max/800/0*0VnMWKBszvJ5iwCf"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Options to create platforms</figcaption></figure><p name="7565" class="graf graf--p graf-after--figure">&zwnj;<strong class="markup--strong markup--p-strong">iOS&nbsp;:-</strong> You’ll see a form asking you for some information, right now we just need the <code class="markup--code markup--p-code">Bundle ID</code>. You bundle ID is same as the app ID you supplied to capacitor in Step 2.</p><p name="42b3" class="graf graf--p graf-after--p">&zwnj;Once you add the Bundle ID, just follow the process to create the app.</p><p name="4db2" class="graf graf--p graf-after--p">&zwnj;<strong class="markup--strong markup--p-strong">Android&nbsp;:-</strong> The difference is that instead of <code class="markup--code markup--p-code">Bundle ID</code>, Facebook calls it “Google Play Package Name” in case of Android.</p><h4 name="0cd6" class="graf graf--h4 graf-after--p">Add/Generate Key&nbsp;Hash</h4><p name="897b" class="graf graf--p graf-after--h4">Since Capacitor builds production builds, it signs your Android app with <code class="markup--code markup--p-code">debug.keystore</code>&nbsp;. When you try to login via Facebook, Facebook needs to know the Key Hash of your system to ensure it’s you who compiled the app. You can add more than one Key Hash as well.</p><p name="5a7e" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Windows System</strong>: (Details <a href="https://stackoverflow.com/a/12577997/5663283"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">here</a>)</p><pre name="57b2" class="graf graf--pre graf-after--p"><strong class="markup--strong markup--pre-strong">$ keytool -exportcert -alias androiddebugkey -keystore "C:\Documents and Settings\Administrator.android\debug.keystore" | "C:\OpenSSL\bin\openssl" sha1 -binary |"C:\OpenSSL\bin\openssl" base64</strong></pre><p name="4e8d" class="graf graf--p graf-after--pre"><strong class="markup--strong markup--p-strong">Mac System</strong>: (Details <a href="https://stackoverflow.com/a/12577997/5663283"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">here</a>)</p><pre name="229e" class="graf graf--pre graf-after--p"><strong class="markup--strong markup--pre-strong">keytool -exportcert -alias androiddebugkey -keystore debug.keystore | openssl sha1 -binary | openssl base64</strong></pre><p name="cb0f" class="graf graf--p graf-after--pre"><strong class="markup--strong markup--p-strong">Hacky solution to know Keyhash:</strong></p><p name="6788" class="graf graf--p graf-after--p">If you don’t want to go through all this hassle, just continue reading the post. Once you build the app in android device and try to login via Facebook, it will show you an error saying</p><pre name="0c22" class="graf graf--pre graf--startsWithDoubleQuote graf-after--p">“xxxxxxxxxxx hash key does not match any saved Hash keys”</pre><p name="e1a5" class="graf graf--p graf-after--pre">At this point, copy the hash-key from the error, and save it in Facebook developer console. 😎</p><figure tabindex="0" contenteditable="false" name="0bab" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 301px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 42.9%;"></div><img class="graf-image" data-image-id="1*xiO5A6vBfpNVU-x_gsC15A.png" data-width="1388" data-height="596" alt="Add hash keys for Facebook login in your Ionic React Capacitor app" src="https://cdn-images-1.medium.com/max/800/1*xiO5A6vBfpNVU-x_gsC15A.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Add hash keys to enable Facebook login in your Ionic Capacitor app</figcaption></figure><h3 name="d697" class="graf graf--h3 graf-after--figure">Step 4&#8202;—&#8202;Setup Facebook Login Plugin and functions</h3><p name="8ec3" class="graf graf--p graf-after--h3">To setup Facebook login in the app, we’ll do following things</p><p name="c71f" class="graf graf--p graf-after--p">4.1 Install Capacitor Facebook Login plugin</p><p name="02c2" class="graf graf--p graf-after--p">4.2 Setup plugin functions for login</p><p name="aac8" class="graf graf--p graf-after--p">4.3 Enable routing between two pages of the app</p><p name="0828" class="graf graf--p graf-after--p">4.4 Control navigation via login / logout from Facebook</p><h4 name="18aa" class="graf graf--h4 graf-after--p">4.1 Install Capacitor Facebook Login&nbsp;plugin</h4><p name="5585" class="graf graf--p graf-after--h4">Install the plugin using</p><pre name="ef0f" class="graf graf--pre graf-after--p">$ npm i --save @rdlabo/capacitor-facebook-login</pre><p name="8e9e" class="graf graf--p graf-after--pre">After this, build your app using following commands</p><pre name="046d" class="graf graf--pre graf-after--p">// Build web assets<br>$ <strong class="markup--strong markup--pre-strong">ionic build</strong></pre><p name="397a" class="graf graf--p graf-after--pre">Add Android platform to the app</p><pre name="4f4c" class="graf graf--pre graf-after--p">// Add android platform<br>$ <strong class="markup--strong markup--pre-strong">npx cap add android</strong></pre><p name="09e5" class="graf graf--p graf-after--pre">After this, if you make any changes to the code or assets, you can copy all that in Android platform using</p><pre name="4a67" class="graf graf--pre graf-after--p">// Copy all changes to Android platform<br>$ <strong class="markup--strong markup--pre-strong">npx cap sync</strong></pre><p name="4227" class="graf graf--p graf-after--pre">To build the app from Android Studio, open the editor using</p><pre name="3dc4" class="graf graf--pre graf-after--p">// Open the project in Android studio<br>$ <strong class="markup--strong markup--pre-strong">npx cap open android</strong></pre><p name="ad06" class="graf graf--p graf-after--pre">In Android studio, locate file <code class="markup--code markup--p-code">android/app/src/main/java/**/**/MainActivity.java</code>, and add the plugin to the initialization list:</p><pre name="1ecc" class="graf graf--pre graf-after--p">this.init(savedInstanceState, new ArrayList&lt;Class&lt;? extends Plugin&gt;&gt;() `{{<br>  ...<br>  <strong class="markup--strong markup--pre-strong">add(jp.rdlabo.capacitor.plugin.facebook.FacebookLogin.class);</strong><br>  ...<br>}}`);</pre><p name="9821" class="graf graf--p graf-after--pre">In file <code class="markup--code markup--p-code">android/app/src/main/AndroidManifest.xml</code>, add the following XML elements under <code class="markup--code markup--p-code">&lt;manifest&gt;&lt;application&gt;</code>&nbsp;:</p><pre name="e3f7" class="graf graf--pre graf-after--p">&lt;meta-data android:name="com.facebook.sdk.ApplicationId"<br>    android:value="<a href="http://twitter.com/string/facebook_app_id"  class="markup--anchor markup--pre-anchor" title="Twitter profile for @string/facebook_app_id"    target="_blank">@string/facebook_app_id</a>"/&gt;<br>&lt;activity<br>    android:name="com.facebook.FacebookActivity"    android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"<br>    android:label="<a href="http://twitter.com/string/app_name"  class="markup--anchor markup--pre-anchor" title="Twitter profile for @string/app_name"    target="_blank">@string/app_name</a>" /&gt;<br>&lt;activity<br>    android:name="com.facebook.CustomTabActivity"<br>    android:exported="true"&gt;<br>    &lt;intent-filter&gt;<br>        &lt;action android:name="android.intent.action.VIEW" /&gt;<br>        &lt;category android:name="android.intent.category.DEFAULT" /&gt;<br>        &lt;category android:name="android.intent.category.BROWSABLE" /&gt;<br>        &lt;data android:scheme="<a href="http://twitter.com/string/fb_login_protocol_scheme"  class="markup--anchor markup--pre-anchor" title="Twitter profile for @string/fb_login_protocol_scheme"    target="_blank">@string/fb_login_protocol_scheme</a>" /&gt;<br>    &lt;/intent-filter&gt;<br>&lt;/activity&gt;</pre><p name="45d3" class="graf graf--p graf-after--pre">And, in file <code class="markup--code markup--p-code">android/app/src/main/res/values/strings.xml</code> add the following lines&nbsp;:</p><pre name="633f" class="graf graf--pre graf-after--p">&lt;string name="facebook_app_id"&gt;[APP_ID]&lt;/string&gt;<br>&lt;string name="fb_login_protocol_scheme"&gt;fb[APP_ID]&lt;/string&gt;</pre><p name="cb9f" class="graf graf--p graf-after--pre">Replace <code class="markup--code markup--p-code">[APP_ID]</code> by your Facebook application Id. Here’s how it looks like</p><figure tabindex="0" contenteditable="false" name="522b" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 683px; max-height: 213px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 31.2%;"></div><img class="graf-image" data-image-id="1*0wIGwDKKo_GhGmIrB8d7GA.png" data-width="683" data-height="213" alt="Add your Facebook app ID in Android project&#8202;—&#8202;Ionic React Capacitor Facebook login" src="https://cdn-images-1.medium.com/max/800/1*0wIGwDKKo_GhGmIrB8d7GA.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Add your Facebook app ID in Android project&#8202;—&#8202;Ionic Capacitor Facebook&nbsp;login</figcaption></figure><h4 name="6fc7" class="graf graf--h4 graf-after--figure">4.2 Setup plugin functions for&nbsp;login</h4><p name="7ac2" class="graf graf--p graf-after--h4">We have to setup four major functions for Facebook functionality</p><ol class="postList"><li name="3846" class="graf graf--li graf-after--p">Login</li><li name="ecac" class="graf graf--li graf-after--li">Logout</li><li name="f729" class="graf graf--li graf-after--li">Check if user is logged in (for auto-log in)</li><li name="4eca" class="graf graf--li graf-after--li">Get user profile information</li></ol><p name="cc8b" class="graf graf--p graf-after--li">Login page will have #1 and #3 functions, while the inner page (Home) will have #2 and #4.</p><h4 name="002d" class="graf graf--h4 graf-after--p">Login Page</h4><p name="8317" class="graf graf--p graf-after--h4">The complete code for Login Page looks like this</p><figure tabindex="0" contenteditable="false" name="65e6" 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/50b5dda62aa24a25a14f3109df808a3d.js %}</div></div><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for embed (optional)">Login page for Facebook login in Capacitor app. Contains Login and auto-login functions</figcaption></figure><p name="16db" class="graf graf--p graf-after--figure">Some basic things</p><pre name="1bf8" class="graf graf--pre graf-after--p">const FACEBOOK_PERMISSIONS = ['public_profile', 'email'];</pre><p name="bf4e" class="graf graf--p graf-after--pre">asks for permission during login. This is the basic permission, but you can ask for more permissions.</p><pre name="ba18" class="graf graf--pre graf-after--p">let user = { token: result.accessToken.token, userId: result.accessToken.userId }<br>let navigationExtras: NavigationExtras = <br>{queryParams: {userinfo: JSON.stringify(user)}};<br>this.router.navigate(["/home"], navigationExtras);</pre><p name="a5ce" class="graf graf--p graf-after--pre">Here, <code class="markup--code markup--p-code">navigationExtras</code> field contains navigation params&nbsp;. These will be accessed in next page from the <code class="markup--code markup--p-code">ActivatedRoute</code>object&nbsp;.</p><p name="5212" class="graf graf--p graf-after--p">Also, <code class="markup--code markup--p-code">getCurrentState</code> function gets the currentState of user. If the user logged in once, and closed the app without logging out, the state will still remain <strong class="markup--strong markup--p-strong">Logged In. </strong>That means, <code class="markup--code markup--p-code">getCurrentState</code> function will get the current state and auto-login the user.</p><h4 name="8bcc" class="graf graf--h4 graf-after--p">Home Page</h4><p name="936d" class="graf graf--p graf-after--h4">The complete code for Home Page looks like this</p><figure tabindex="0" contenteditable="false" name="6538" class="graf graf--figure graf--iframe is-defaultValue 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/3449649afeaf184a28debdd0a6b6705e.js %}</div></div></figure><p name="f34a" class="graf graf--p graf-after--figure">The <code class="markup--code markup--p-code">userID</code> and <code class="markup--code markup--p-code">token</code> sent from first page is accessed via <code class="markup--code markup--p-code">this.route.queryParams</code> object, where <code class="markup--code markup--p-code">this.route</code> is the <code class="markup--code markup--p-code">ActivatedRoute</code></p><h4 name="4ade" class="graf graf--h4 graf-after--p">4.3 Enable routing between two pages of the&nbsp;app</h4><p name="c742" class="graf graf--p graf-after--h4">The routes are defined in <code class="markup--code markup--p-code">app-routing.module</code> file like this</p><pre name="5f1c" class="graf graf--pre graf-after--p">const routes: Routes = [<br> { path: '', redirectTo: 'login', pathMatch: 'full' },<br> { path: 'home', loadChildren: () =&gt;  import('./home/home.module').then(m =&gt; m.HomePageModule) },<br> { path: 'login', loadChildren: () =&gt; import('./login/login.module').then(m =&gt; m.LoginPageModule) }<br>]</pre><h4 name="11e9" class="graf graf--h4 graf-after--pre">4.4 Control navigation via login / logout from&nbsp;Facebook</h4><p name="51dc" class="graf graf--p graf-after--h4">Once user is successfully logged in, we want to redirect to <code class="markup--code markup--p-code">Home</code> page. And when user logs out, we want to come back to <code class="markup--code markup--p-code">Login</code> page.</p><p name="a14b" class="graf graf--p graf-after--p">On both pages, we use the following to redirect to pages. <code class="markup--code markup--p-code">ExtraInfo</code> carries info from one page to another in form of string</p><pre name="296a" class="graf graf--pre graf-after--p">this.router.navigate(["/pageUrl"], ExtraInfo);</pre><h3 name="7b29" class="graf graf--h3 graf-after--pre">Step 5&#8202;—&#8202;Build and Test your app on&nbsp;Android</h3><p name="b78e" class="graf graf--p graf-after--h3">At this point, you have all the Facebook Login stuff built-in, Android app setup and Facebook app also setup. Build the app once again after all changes using</p><pre name="94e5" class="graf graf--pre graf-after--p">// Build web assets<br>$ <strong class="markup--strong markup--pre-strong">ionic build<br></strong>// Copy all changes to Android platform<br>$ <strong class="markup--strong markup--pre-strong">npx cap sync</strong></pre><p name="f517" class="graf graf--p graf-after--pre">Build the app on Android device using Android studio. You should be able to login via Facebook, and reach the inner page where you see the user information. Following GIF shows the login flow in my OnePlus device</p><figure tabindex="0" contenteditable="false" name="159f" 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*lgu4HL6LPgxSF0sKYnucSQ.gif" data-width="350" data-height="622" alt="Facebook login, auto-login and logout in Capacitor app with Ionic Angular" src="https://cdn-images-1.medium.com/max/800/1*lgu4HL6LPgxSF0sKYnucSQ.gif"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Facebook login, auto-login and logout in Capacitor app with Ionic&nbsp;Angular</figcaption></figure><p name="d8bc" class="graf graf--p graf-after--figure">The login success response looks like following</p><figure tabindex="0" contenteditable="false" name="031d" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 186px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 26.6%;"></div><img class="graf-image" data-image-id="1*sbo4EGrPJ-6bUI-dAZFUjA.png" data-width="1009" data-height="268" alt="Response after successful Facebook login" src="https://cdn-images-1.medium.com/max/800/1*sbo4EGrPJ-6bUI-dAZFUjA.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Response after successful Facebook&nbsp;login</figcaption></figure><p name="c6fc" class="graf graf--p graf-after--figure">When you call the graph API to fetch user’s profile picture, the response looks like this</p><pre name="354d" class="graf graf--pre graf-after--p">{<br>   "id": "10214671387924571",<br>   "name": "Abhijeet Rathore",<br>   "picture": {<br>      "data": {<br>         "height": 50,<br>         "is_silhouette": false,<br>         "url": "https://platform-lookaside.fbsbx.com/platform/profilepic/?asid=10214671387924571&amp;height=50&amp;width=50&amp;ext=1572869974&amp;hash=AeSvjMz4Wkb3Y1dY",<br>         "width": 50<br>   }<br>}</pre><p name="399b" class="graf graf--p graf-after--pre">Congratulations&nbsp;!! You have successfully integrated Facebook login in your Ionic Angular Capacitor app. 🎉</p><h3 name="49f9" class="graf graf--h3 graf-after--p">Conclusion</h3><p name="40e8" class="graf graf--p graf-after--h3">In this post you learnt how to implement Facebook login in your Ionic Capacitor app in Angular. Social logins are very important part of your apps, as they make users trust your apps more. It is also easy to use, and users don’t have to remember any passwords. You can always link the Social logins with your server as well. Firebase has a ready-to-integrate solution for this.</p><blockquote name="9ed2" class="graf graf--blockquote graf-after--p graf--trailing"><strong class="markup--strong markup--blockquote-strong"><em class="markup--em markup--blockquote-em">Code for this tutorial is available on Github repo </em></strong><a href="https://github.com/enappd/capacitor-facebook-login"  class="markup--anchor markup--blockquote-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--blockquote-strong"><em class="markup--em markup--blockquote-em">ionic-angular-capacitor-facebook-login</em></strong></a></blockquote></div></div></section><section name="a738" 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"><h3 name="8963" class="graf graf--h3 graf--leading">Next Steps</h3><p name="3e7f" class="graf graf--p graf-after--h3">Now that you have learned the implementation of Facebook Login in Ionic Capacitor app in Angular, you can also try following blogs for other <strong class="markup--strong markup--p-strong">Ionic apps</strong></p><h4 name="a417" class="graf graf--h4 graf-after--p">Ionic Angular Capacitor</h4><ul class="postList"><li name="c59a" class="graf graf--li graf-after--h4"><a href="https://enappd.com/blog/play-music-in-ionic-capacitor-apps/112"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Music Player</a></li><li name="ddc2" class="graf graf--li graf-after--li"><a href="https://enappd.com/blog/html5-games-in-ionic-capacitor-using-phaser/115"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Create HTML5 games in Ionic Capacitor apps using Phaser</a></li><li name="22e8" class="graf graf--li graf-after--li"><a href="https://enappd.com/blog/qr-code-and-barcode-scanning-with-ionic-capacitor/127"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Barcode and QR code scanning in Ionic Capacitor apps</a></li></ul><p name="18ee" class="graf graf--p graf-after--li">If you need a base to start your next <strong class="markup--strong markup--p-strong">Capacitor app</strong>, you can make your next awesome app using <a href="https://store.enappd.com/product/capacitor-full-app-with-ionic-angular/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Capacitor Full App</a></p><figure tabindex="0" contenteditable="false" name="7553" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 761px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 108.7%;"></div><img class="graf-image" data-image-id="1*9eKBtNJaAYPMzyZvyifWIQ.png" data-width="736" data-height="800" alt="Capacitor Full App with huge number of layouts and features" src="https://cdn-images-1.medium.com/max/800/1*9eKBtNJaAYPMzyZvyifWIQ.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Capacitor Full App with huge number of layouts and&nbsp;features</figcaption></figure><h4 name="35e7" class="graf graf--h4 graf-after--figure">Ionic React Capacitor</h4><ul class="postList"><li name="93d7" class="graf graf--li graf-after--h4"><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 Ionic React Capacitor apps</a></li><li name="0f16" class="graf graf--li graf-after--li"><a href="https://enappd.com/blog/twitter-login-in-ionic-react-capacitor-app/121"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Twitter Login in Ionic React Capacitor apps</a></li><li name="a9e7" class="graf graf--li graf-after--li"><a href="https://enappd.com/blog/google-login-in-ionic-react-capacitor-apps/122"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Google Login in Ionic React Capacitor apps</a></li><li name="8885" class="graf graf--li graf-after--li"><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-capacitor</a></li><li name="6594" 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="4f4f" 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="c5a7" 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></ul><p name="d39b" 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="074b" 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="0*AxzmDBUVguZ1kw_i.jpeg" data-width="600" data-height="600" src="https://cdn-images-1.medium.com/max/800/0*AxzmDBUVguZ1kw_i.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="9d27" class="graf graf--h4 graf-after--figure">Ionic Angular&nbsp;Cordova</h4><ul class="postList"><li name="85a8" 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="5acf" 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="dfc7" 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="6667" 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="91ad" 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="a628" 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="779c" 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="38ee" 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="0711" 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="12ae" 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="001a" 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*lqQcM0JyxN7nFQdL.jpeg" data-width="560" data-height="353" src="https://cdn-images-1.medium.com/max/800/0*lqQcM0JyxN7nFQdL.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="8e64" class="graf graf--p graf--empty graf-after--figure graf--trailing"><br></p></div></div></section></div></article></main>