In this ionic tutorial I will show you what are Progressive Web Apps, why you should definitely consider them for your next project, and also how easy is to build a feature complete PWA with Ionic Framework.

Ionic is a step forward for Progressive Web Apps. The Ionic Framework team is doing a great job positioning themselves as the Framework of choice to build PWAs.

This post is part of the "Mastering Ionic Framework" series which deep dives into Ionic more advanced stuff. Don't be afraid, if you are new to Ionic, I strongly recommend you to first read our Introduction to Ionic tutorial.

In our previous post Ionic 4 vs Ionic 3 — What you need to know about Ionic 4 we surfaced the main differences between Ionic 3 and Ionic 4. Ionic 4 presented big changes because the framework was completely rebuilt from the ground up using standard Web APIs, and each component is packaged up as a Web Component.

Then, when Ionic 5 was released, we created the post What's new in Ionic 5 - Migration and Free Starter where we explain how to take advantage of the new benefits from Ionic 5.

Although there were some important changes, the big picture hasn't changed much from Ionic 4 to Ionic 5, so you shouldn't be afraid to make the change.

In this series of posts we have already talked about Web Components, Shadow DOM, CSS Variables, and Stencil.
To complete the in-depth analysis of Ionic Framework, besides covering everything about Progressive Web Apps on this post, we will also be addressing Ionic Navigation using Angular Router in our third and final post.

At IonicThemes we are big fans of Learning by example, that's why all our ionic tutorials include a complete and free ionic code example that you can reuse in your ionic projects. We strive to create the best content for Ionic Framework, both tutorials and templates to help the Ionic community succeed. We work towards empowering developers to achieve a free life through coding. That's what motivates us at IonicThemes everyday.

Check out our detailed and professional Ionic Starter App crafted with love and dedication to help you create better apps and supercharge your productivity.

Progressive Web Apps are a synergy of the very best between Web and Native worlds.

PWAs are web applications that load like regular web pages or websites but can offer the user functionalities traditionally available only to native mobile applications such as push notifications, working offline, and device hardware access.

They are a new way to offer incredible mobile app experiences that are highly optimized and accessible completely on the web. They are a cross-device solution.

PWAs are useful to users from the very first visit in a browser tab as there's no need to go to the App Store and install the app.

The initial "download" of a PWA is minimal (a few KB's with just the assets needed for the basic first interaction with the app) in contrast with native apps where you download the full app upfront (quite some MB of assets).

It's worth mentioning that PWAs aren't a new framework or technology. They are a set of best practices to make a web application function similar to a desktop or mobile application. The ideal situation would be to have an experience so seamless and uniform that the user is unable to tell the difference between a Progressive Web App and a native mobile app.

PWAs combine the open standards of the web offered by modern browsers to provide rich mobile experiences.

Progressive Web Apps are known for loading in record time even if the network is spotty since they can control their own cache. To keep customers engaged, they provide push notifications and have icons on the home screen, while still loading as a top level, full-screen experience.

The advantage of this new approach is that it lowers the cost of customer acquisition, while improving the conversion rates. It's a great tool for onboarding new customers, since the discoverability of the web makes them perfect for its advertising and social media communication purposes.

ionic pwa

To understand why we need PWAs, let's first talk about some of the biggest challenges we are facing today with native and responsive web apps:

Internet speed: depending on where you live internet may be a nightmare. You may have not realized this, but 60% of the world's population is still using 2G internet.

Slow website load: Do you know how long a user waits to close a website if it's too slow? Only three seconds! 50% of users abandon a website if it loads too slow.

High friction: People don't want to install a native app for everything. In the United States, smartphone users spend almost 80% of their total app usage on their favorite three apps. Contrast this with how many new web sites you visit each month. Also think about how many apps you downloaded and eventually ended up using just once or very few times?

User engagement: Responsive mobile web sites have much more reach than native apps, however they lack basic functionalities like push notifications and offline support. That causes that most of the users of responsive web sites are not actively engaged compared to native apps engagement levels.

PWAs help solving these problems. Let's go through the main benefits of using progressive web apps.

Benefits first time seen on a web app:

  • Web app install banner prompt
  • Launch from user's home screen
  • Full screen browser mode
  • Push notifications for web app
benefits of progressive web apps

CONNECTIVITY INDEPENDENT - Enhanced with service workers to work offline or on low-quality networks.

APP LIKE - Feels like an app to the user with app-style interactions and navigation.

FRESH - Always up-to-date thanks to the service worker update process.

DISCOVERABLE - Due to the web nature of Progressive Web Apps, search engines are able to find them! This is super important for SEO purposes.

Re-ENGANGABLE - Makes re-engagement easy through features like push notifications.

INSTALLABLE - Allows users to "keep" apps they find most useful on their home screen without the hassle of an app store middleman.

LINKABLE - Easily shareable via URLs.

Integrated and Engaging User Experience

PWAs feel and behave like native apps. They sit in a user's home screen, send push notifications like native apps, and have access to some device functionalities like native apps. The experience feels seamless and integrated. Because we can send notifications to a user, we can really drive the engagement up by keeping the user notified and engaged with the app like we do in native apps.

Engaging is not only about push notifications, in my opinion is paramount to have an unobtrusive way for users to try the service and taste the potential value of your product early on. If you are interested on this topic, previously we wrote a post about Mobile UI components and best practices to handle User Engagement.

In Twitter's case, when someone shares a link of a tweet and people click on it, it will open that tweet conversation. Browsing around and feeling the experience of Twitter without installing anything is a good way to showcase the value of Twitter without any hurdles.

You can even go a step further by embracing PWA capabilities and offer users to get a notification every time someone mentions them. Just exactly like the Twitter native mobile app.

Following the Progressive Web App pattern to provide native experience on mobile phones through web standards, people can use their favourite services directly on their phones without downloading any native app.

A side note about Navigation

Navigation is one of the most important parts of an app. Solid navigation patterns help us achieve great user experience while a great router implementation will ease the development process and at the same time make our apps discoverable and linkable.

Navigation is indeed one of the most important elements of user experience that every developer must include on its checklist while creating any kind of app. A bad navigation can frustrate users to an extent that they end up uninstalling the app and even posting a negative review about your app on the app store.

Find more information about how to design a good navigation strategy for your Ionic Application.

Do you want to create a PWA with Ionic but don't know how to start? Don't worry, you can leverage on Ionic 6 Full Starter App - PRO. It's an Ionic 5 PWA that you can use to jump start your PWA development and save yourself hundreds of hours of design and development.

It includes more than 100 carefully designed views and components. It has full support for PWA with Angular. Try it on your phone as a PWA to see how it works!

ionic starter app

Cheaper and Improved User Acquisition

The open nature and discoverability of the web compared to App Stores translates into a more democratic and organic way to find content, and this translates into a greater reach of users, less friction and lower user acquisition costs.

Convenience is a key factor when talking about user acquisition. Some industries like gaming, retail, content publishing and other "in-the-moment" services rely on the web and SEO for driving traffic and user acquisition. By adding PWAs to their mobile strategy they can benefit greatly.

Let's imagine for a moment that you're looking for a quick dinner delivery from your favorite restaurant. You go and search for its website and look to place an order, but you are pushed to download an app in order to be able to place the order. What would you do? Do you download it? Do you call the restaurant? Or do you abandon the idea all together?

Uber pictured this and put a lot of advertising banners around airports featuring a PWA url. This way when a tourist want to use Uber for the first time, they can avoid going through the Play Store or App Store to install the app. Using the Uber PWA is really simple, people just have to open a URL and use Uber services directly without having to install anything.

Friction is something you should be aware of, it's important to understand that pushing people into the App Store isn't the silver bullet some brands think it is. Asking users to give up valuable space on their phone for an app they may never open often can hurt customer relationships rather than make them stronger - and could risk losing visitors altogether.

Sometimes it doesn't make sense to download an app before it proves valuable to you. Let's see some examples so you can get what I mean:

  • Booking transport, either bus, train, or taxi. When you arrive at a new city you want a quick and light solution for transportation.
  • Event information for schedule, speaker list, and venue map. Doesn't make sense to ask the user to download an app just to use it for a couple hours.
  • Online shops, where brands usually promote the products through social media. Would users convert if you add an extra step to the funnel by requiring them to download your app from the app store?
  • Queue system, for bank, hospital, etc. Imagine every time you go to a new place that needs you to queue and you need to download an app just to get the queue number. Complete nonsense.

Brands are seeking to overcome this user acquisition challenge, and Progressive Web Apps are becoming the way to go.

Better Performance, Conversion and Engagement

PWAs provide experiences that are consistently fast. From the moment a user downloads an app to the moment they start interacting with it, everything happens really fast. Because they leverage cache, repeated uses of the app don't have to hit the network resulting in an even faster experience.

PWAs are better for your business

Overall I'm seeing a vast amount of scenarios where PWAs outperforme their native and mobile web counterparts. I find PWAStats a great resource to articulate this claiming.

Take the experience and results top brands are having with their PWA endeavors.

  • Starbucks. The Starbucks PWA has increased daily active users 2x. Orders on desktop are nearly the same rate as mobile.
  • Uber. Uber's PWA was designed to be fast even on 2G. The core app is only 50k gzipped and takes less than 3 seconds to load on 2G networks.
  • Tinder. Tinder cut load times from 11.91 seconds to 4.69 seconds with their new PWA. The PWA is 90% smaller than Tinder's native Android app. User engagement is up across the board on the PWA.
  • Pinterest. Pinterest rebuilt their mobile site as a PWA and core engagements increase by 60%. They also saw a 44% increase in user-generated ad revenue and time spent on the site has increased by 40%.
  • Flipkart. Flipkart's PWA is driving 50% of its new customer acquisition. Nearly 60% of visitors to the PWA had previously uninstalled the native app primarily to save space.
  • OLX. OLX experienced 250% more re-engagement using push notifications and 146% higher click-through rate on ads. The PWA takes 23% less time to interactive resulting in 80% lower bounce rates.
  • Infobae. Infobae's PWA beta has 230% longer session and 3× more page views than the previous mobile site.
  • Selio. Selio's average customer acquisition cost for Progressive Web Apps is 10× less than for native apps.
  • Google. Google found that Progressive Web App install banners convert 5-6× more often than native install banners. More than half of users who chose to install a native app from these banners fail to complete installing the app whereas PWA installation is near-instant.

The combination of cheaper user acquisition costs, improved conversions and engagement metrics make PWAs a no-brainer. Even more if the user experience is guaranteed to be on par with native apps.

Still have doubts about PWAs? Boost your app strategy with greater reach and engagement by creating yours!

Conventional wisdom is a trap

While talking to clients, I hear quite often "market leaders have native apps and it's working for them, so why not us?".

Don't get me wrong, native apps are great, but it's not just the app, it's the intrinsic cost of acquiring and engaging users, and building a real business on top of the app. For an app "to be working", all sides of the equation need to be working.

There are also some structural challenges when it comes to learning that a native app may not be working.

First, it's really rare to see true A/B comparisons: funding both PWA and native app development and comparing acquisition and engagement between them.

Second, it's very common to see organizations that have separate teams for native and web endeavours, maybe even funded from different sources (marketing, R&D, etc) or even outsourced. This siloing often leads to long learning cycles, and with scarce information and communication is easy to miss the big picture.

You may be growing your native app but not actually growing the business. Having a clear overview of long-term vs short-term metric growth and what leverages each platform (web, native, pwa) is key. Take into consideration that different platforms may be ruled by different economics (for example, native apps are vastly more expensive to distribute than web).

ionic templates

Timing

Add to Home Screen, Push Notifications and Offline support were not possible a few years ago. Until Progressive Web Apps arrived, it wasn't possible to engage users who wanted more of a service in all the ways that native apps could. The lack of push notifications and the presence on the homescreen stunted engagement.

Also, the lack of meaningful offline behavior meant it was natural for services and users to choose the native app route once they decided a service was worthwhile.

Bad experiences and Misleading numbers

A typical technology path many organizations followed was first pretend their desktop website was fine because users would eventually pinch/zoom accordingly. Then "responsive" become a thing and everybody jumped over without slimming down JS, ads, images, etc.

For the reasons mentioned above besides the timing issues we mentioned earlier, the "responsive" endeavour was doomed from the get go. With poor results from responsive web apps, experimenting with native apps was the logical next step.

At first, early engagement numbers from native apps tend to be strong compared to "responsive web" sites. This follows from the historical feature and performance gap but also from a more subtle effect: users who are willing to download and install a native app, are likely already heavily engaged with the service.

Unfortunately, many will eventually hit the wall in terms of cost/benefit to native app distribution. It's blindingly expensive to drive native app installs if you aren't #1 in your market.

It's just hard to learn the true cost/benefit of native app strategies.

When making the decision, strive for the big picture and realize that your business goes beyond the app you building.

Enough talking about the business side, let's dive in and see how Ionic Framework is the ideal tech to build our Progressive Web App.

As we mentioned above, for a web app to be considered a PWA, it needs to comply with the following principles. Let's see how Ionic Framework addresses each of them.

PWA PrincipleHow Ionic handles it
Progressive - Works for every user, regardless of browser choice because it's built with progressive enhancement as a core tenet.Ionic uses many cutting edge web standards and APIs. Despite the fact that some of those don't have full support across browsers, Ionic still works. In that sense, Ionic is considered to be progressive.
Responsive - Fits any form factor: desktop, mobile, tablet, or whatever is next.Ionic UI components are known for its flexibility. You can easily build a responsive UI with Ionic.
Connectivity independent - Enhanced with service workers to work offline or on low-quality networks.Ionic apps can be easily combined with service workers to make apps work offline.
App-like - Feels like an app to the user with app-style interactions and navigation because it's built on the app shell model.Ionic framework is mobile first, all of Ionic components even adapt to the different platforms (ios, material design).
Fresh - Always up-to-date thanks to the service worker update process.Using different caching strategies inside our service workers we can control the freshness of our cached resources.
Safe - Served via HTTPS to prevent snooping and to ensure content hasn't been tampered with.We can achieve safety for our content by using a hosting provider that has HTTPS support.
Discoverable - Is identifiable as an "application" thanks to W3C manifest and service worker registration scope, allowing search engines to find it.The changes in how the router works from Ionic 4 onwards, made discoverability for our apps easy to achieve.
Re-engageable - Makes re-engagement easy through features like push notifications.Ionic plays really nice with other libraries and packages that enable us to setup push notifications in a breeze.
Installable - Allows users to "keep" apps they find most useful on their home screen without the hassle of an app store.Ionic makes easy to achieve all the principles that enable our app to be installed (web app manifest, HTTPS, registered service worker).
Linkable - Easily share via URL, does not require complex installation.With the Ionic Angular router, we don't have to rely on deep-links anymore to link to the different parts of our web app.

Check the Core Progressive Web App checklist for more information about this.

Get your PWA up and running with Ionic

When it comes to the implementation, Ionic Framework presents different ways of building apps.

In an effort to attract new developers and become framework agnostic while embracing web components standard, Ionic can be used out of the box without any companion framework.

The @ionic/core package contains the Web Components that make up the reusable UI building blocks of Ionic Framework. These components are designed to be used in traditional frontend view libraries/frameworks (such as Stencil, React, Angular, or Vue), or on their own through traditional JavaScript in the browser.

On the other hand, honoring the well known Angular relationship with Ionic from the early days of the framework, Ionic has an option to enhance the development experience and use Ionic in combination with the Angular capabilities you already know and love. The @ionic/angular package comes with Angular specific building blocks on top of @ionic/core components.

When it comes to building a Progressive Web App with Ionic, we can choose either way, but we have to take into consideration some details as we will need extra help to handle some details of the implementation such as service workers and web manifest.

The new features in modern browsers that allow PWAs to work are web manifest files and service workers.

PWA Web Manifest

The web manifest is a simple JSON file that defines the fundamental parameters of the PWA, icons, app name, colors, screen orientation, etc. It tells the browser about your PWA and how it should behave when installed on the user's desktop or mobile device

PWA Service worker

The Service workers are the real key to the enhanced experiences that PWAs can offer. Acting essentially as a proxy between the user and the network, they are little javascript helpers that do the cool things that allow PWAs to work, such as caching data (and deciding when and how to use the cached info - for example to overcome a bad network connection), event triggers, taking care of push notifications, organizing updates and so on.

In other words, a service worker is a script that your browser runs in the background, separate from a web page, opening the door to features that don't need a web page or user interaction.

All these configurations are already solved in our Ionic PWA Starter.

Framework agnostic PWA

Ionic has a PWA Toolkit that has everything you need to build progressive web apps without the dependency on a frontend framework such as Angular, React or Vue.

However, under the hood it uses Stencil for compiling and building the app, Workbox to enforce best practices and easing the boilerplate needed when working with service workers and cache strategies (both crucial to build PWA's), and Ionic Core for all the beautiful UI components Ionic is known for.

To be honest, we haven't looked in detail this approach. Although it has a solid foundation and looks promising, with new libraries or frameworks I tend to wait a little bit until they get more mature and stable. Besides that, I really like building Angular apps, so I might be a little bit biased.

Enhancing your PWA with Angular

If we choose this path, besides Ionic and Angular (@ionic/angular package) we will also need the @angular/pwa package to setup and ease the configuration of the service worker and web manifest in our project.

For more information, follow this link on adding service workers to your Angular app.

I have to admit that I feel more comfortable with this approach as Angular provides a solid, future proof framework to build apps. On top of that, adding Ionic with all the cool features it comes ends up in a winner combination.

In conclusion, the framework agnostic approach using the Ionic PWA Toolkit (that comes with Stencil, Workbox and Ionic Core) is really just a starting point for building an app. Following the Angular enhancement approach (which includes the @angular/pwa package) is ideal to add PWA features to an already existing @ionic/angular app.

It's worth mentioning that you can't combine the PWA Toolkit with the @ionic/angular package. They use a different set of underlying libraries and are not intended to be used together. You either go with the @ionic/angular + @angular/pwa approach or with the PWA Toolkit (@ionic/core + Stencil + Workbox) approach.

ionic pwa template

Ionic is an excelente choice to build PWAs

Embracing the flexibility Ionic provides, either way will get you covered to build a progressive web app.

As I mentioned above, most of the principles that constitute a PWA are already baked into Ionic (Responsive, App-like, Discoverable, Linkable).

The others (Connectivity independent, Fresh, Re-engageable, Installable) relate to service workers and web manifest specification. These are handled both by Workbox or @angular/pwa.

The Progressive principle is intrinsic and refers to the ability to adapt to the features list available in the platform the app is running. For example if you run a PWA in Chrome on iOS, service workers are not available but that doesn't prevent the PWA from working.

The remaining Safe PWA principle rely on your hosting provider respectively.

Today most browsers do support service workers and the use of HTTPS is well spread.

Probably, the not so well known, and thus more difficult to grasp, are the principles related to service workers and web manifest. Luckily both Workbox and @angular/pwa packages can ease the process of implementing and configuring some of their most hidden details.

If you want to learn more about this, follow this awesome guide on service workers configuration using the @angular/pwa package.

Let's get into the practial part of this Ionic PWA tutorial.

We will create a sample PWA that I will focus on showing you how easy it is to go from 0 to 1 in terms of the Progressive Web App Principles checklist using Ionic Framework.

Then, we will add more complex functionalities such as push notifications and finally we will add some CSS adjustments to make the app look great.

Did you know that we recently released Ionic 6 Full Starter App - PRO version? It's an Ionic PWA template that you can use to jump start your PWA development and save yourself hundreds of hours of design and development. Try it on your phone as a PWA.

ionic 5 starter

Adding PWA Capabilities - From 0% to 100%

Let's start by creating a new Ionic Angular app.

$ ionic start myPWA sidemenu --type=angular

Note: In the setup process, I opted-out from Capacitor because in this ionic tutorial we are just focusing on the PWA nature of Ionic.

Let's be accountable and test how a blank Ionic app scores in our PWA checklist.

To perform this audits we are gonna use Google suggested tool, Lighthouse. In particular, we are going to install and use the Lighthouse command line utility.

npm install -g lighthouse

It's really simple to use, just run lighthouse URL-TO-TEST --view

Note that we run Lighthouse with the --view parameter to immediately open the HTML report in your browser.

#1 Running an Ionic App in a local dev server

Start the development server by running ionic serve (this will serve our app in localhost on port 8100).

Then, perform the PWA audit with Lighthouse by running:

lighthouse http://localhost:8100 --view

Ionic PWA Lighthouse

The initial audit has bad results due to the fact that we are serving the app from a development local server and also because the code is not built using performance enhancements (minification, etc).

#2 Running an Ionic App in a local production server

This time we will build our app with performance in mind. By running ionic build --prod we will be executing the build process with performance enhancements, and will get the outputs on our /www folder.

Besides a production build, we will also run our app with a more suitable web server (to use instead of the development server that comes with the Ionic CLI). For this sake we are going to use the http-server package. This package enables you to create a local web server to serve the contents of any directory on your computer.

npm install -g http-server

Using the http-server utility is realy easy, just run http-server FOLDER-PATH -p PORT

Start the http-server by running http-server ./www -p 8888 (this will serve our app in localhost on port 8888) and then perform the audits with Lighthouse by running:

lighthouse http://localhost:8888 --view

Ionic PWA

Although we improved from the Performance, there is still progress to be made. We haven't even talked about any of the principles that constitute a PWA. We will cover that right away.

#3 Running an Ionic App with @angular/pwa in a local production server

As we mentioned before, the two main requirements of a PWA are a Service Worker and a Web Manifest. While it's possible to add both of these to an app manually, I strongly suggest using the @angular/pwa package to automatically add a service worker and an app manifest to the app. To add this package to your app, simply run:

ng add @angular/pwa

It's time to see how the Ionic application performs now that it has PWA capabilities. Build the app again to include the new PWA features by using ionic build --prod, then start the http-server by running http-server ./www -p 8888 and then perform the PWA audits with Lighthouse by running: lighthouse http://localhost:8888 --view.

Ionic PWA

Look how we drastically improved the progressive web app score. We got 3/3 in Fast and Reliable, 3/3 in Installable and 6/8 in PWA Optimized and this is because we are serving the project from our local server (localhost) and it doesn't have HTTPS enabled. If you remember what we mentioned above, having a safe connection is one of the key principles that constitute a PWA.

This is the current status of our Ionic Framework App in terms of PWA completeness:

Progressive
Responsive
Connectivity independent
App-like
Fresh
SafeMissing because we are serving the app from a local server without HTTPS enabled
Discoverable
Re-engageable - Makes re-engagement easy through features like push notifications.Capable, not implemented.
Installable
Linkable

Also, if you check the Lighthouse recommendations for our App regarding PWA score you will see the following:

Create a PWA in Ionic

#4 Running an Ionic App with @angular/pwa deployed to Firebase Hosting

Final sprint, let's add HTTPS support to achieve 100/100 score!

There are many hosting providers that offer HTTPS support, among them I find the Firebase Hosting product super easy to work with besides it's free and provides many benefits for Progressive Web Apps, including fast response times thanks to CDN's, HTTPS enabled by default, and support for HTTP2 push. Follow me while I show you how to deploy your Ionic PWA to Firebase.

If you want to learn more about using Firebase with Ionic Apps, check our series of posts covering Authentication with Firebase, Ionic CRUD with Firebase, Firebase Storage, Firebase Database.

Let's start by installing the Firebase CLI:

$ npm install -g firebase-tools

With the Firebase CLI installed, run firebase init from within your project's folder and select to add Hosting feature. Then follow the wizard to create a new Firebase project.

Ionic PWA with Firebase

This will generate a firebase.json config file. Make sure caching headers are set correctly like in the following code:

{
  "hosting": {
    "public": "www",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "headers": [
      {
        "source": "/build/app/**",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "public, max-age=31536000"
          }
        ]
      },
      {
        "source": "sw.js",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "no-cache"
          }
        ]
      }
    ]
  }
}

Now run ionic build --prod to rebuild our Ionic PWA with production optimizations.

That's it! Now simply deploy the app to Firebase by running firebase deploy and once the app is deployed, perform the audits with Lighthouse by running:

$ lighthouse https://your-app-url.web.app --view

pwa with ionic framework

Congratulations! We built a progressive web app with Ionic Framework with all the principles covered.

Although we achieved a great score in the Progressive Web Apps checklist, we need to go a step further to complete the implementation of the Push Notifications feature that constitutes the Re-Engageable principle.

In theory, all the mechanisms to make push notifications work in our PWA are already baked inside the Angular Service Worker that comes with @angular/pwa.

But push notifications require much more than just asking users for permissions to send notifications, we also need to setup and configure a push server that will handle the delivery of the notifications to the users in their associated devices.

Don't worry, this complete guide also covers adding Push Notifications to your Ionic PWA!

As I mentioned before, push notifications are one of the most important techniques to make our product or service more re-engageable.

Push Notifications are something normal in native mobile application such as iOS and Android apps, when the application is closed users still received the notifications. Good news, we can achieve the same experience with Progressive Web Apps!

In this ionic PWA tutorial we will go the extra mile and explain how to add push notifications to the Ionic Angular app we created earlier. For this purpose we are going to use Firebase Cloud Messaging as a push server to handle the delivery of notifications across platforms and devices.

Using FCM with Ionic

If we wanted to implement it ourselves without using Firebase Cloud Messaging (FCM), we would need to somehow figure out how to find the device, connect to it and send data. FCM can do all this work for us. We can tell what's the message and who to deliver it to and it will take care of the delivery. In my opinion it's an incredible tool that's completely free and really easy to set up.

The other piece that completes the push notifications implementation is an application server that will tell FCM what notification and to whom should be delivered. There are many ways you can build that.

If you already have a backend API, then you can easily integrate Firebase SDK into your tech stack and problem solved.

Otherwise, if you decided to go serverless (not using a centralized server), you can use a function-as-a-service offering like Firebase Cloud Functions that will let you run a piece of JavaScript code in the cloud, without having to care about where and how it's executed.

For simplicity we won't cover this on this post. We will just test everything is working by hitting FCM directly using cURL.

Adding Firebase to an Angular project

We have lots of tutorials about Firebase and Ionic, but specially I recommend you to check Building a Ionic Firebase App step by step to see how to add many great Firebase features into your Ionic Framework app.

Although we are building an Ionic app, we are relying on Angular framework to build these functionalities.

This is a strong point to Angular. It has many official libraries and packages that make easy to add new functionalities like:

  • Server Side Rendering (@angular/universal)
  • Progressive Web Apps capabilities (@angular/pwa)
  • Service Workers (@angular/service-worker)
  • Material Design (@angular/material)
  • Firebase (@angular/fire)

The official @angular/fire library has many modules to help us interact with the different Firebase features. Also, at IonicThemes we have other posts explaining how to use these features from an Ionic App:

  • Database(s)
    • Cloud Firestore - AngularFirestore
    • Realtime Database - AngularFireDatabase
  • Authentication - AngularFireAuth
  • Cloud Storage - AngularFireStorage
  • Push Notifications - AngularFireMessaging
  • Cloud Functions - AngularFireFunction

First of all, we will need to create a Firebase project. We have already done this when we deployed our sample app to firebase.

Proceed to install the dependencies to @angular/fire:

$ npm install firebase @angular/fire --save

Now please follow this guide to create a Firebase Web Project and bind it to our Ionic App.

Make sure your setup the firebase configuration in your Angular environment files.

export const environment = {
  production: false,
  firebase: {
    apiKey: 'YOUR_API_KEY',
    authDomain: 'YOUR_AUTH_DOMAIN',
    databaseURL: 'YOUR_DATABASE_URL',
    projectId: 'YOUR_PROJECT_ID',
    storageBucket: 'YOUR_STORAGE_BUCKET',
    messagingSenderId: 'YOUR_SENDER_ID'
  }
}

Finish the setup by importing the corresponding AngularFire modules in your app.module.ts file:

import { AngularFireModule } from '@angular/fire';
import { AngularFireMessagingModule } from '@angular/fire/messaging';

...

imports: [
  BrowserModule,
  AngularFireModule.initializeApp(environment.firebase),
  AngularFireMessagingModule
],
...

Setting up the Firebase Cloud Messaging Service Worker

Push Notifications only make sense if you are able to receive them even if the application is not in the foreground. This is possible to achieve in modern web applications thanks to service workers.

A service worker is a piece of JavaScript code that is able to run in the background, independently of the website which loaded it.

As I mentioned before, service workers are used mostly for two things:

  • Providing caching and offline access
  • Push Notifications

In our case, we are using @angular/service-worker that comes with @angular/pwa to handle caching and offline stuff in our Ionic PWA.

Although the @angular/service-worker has utilities to handle push notifications, we will use @angular/fire push utilities instead as they are specifically build to work with Firebase Cloud Messaging.

Houston we have a problem

So, the thing is, you can only register one service worker. And we are using different service workers both for caching/offline support, and push notifications. Worsening the situation, the official AngularFire documentation warns about possible incompatibilities between AngularFireMessaging and the Angular Service Worker.

Maybe I'm not completely understanding the technical incompatibilities between them, but I managed to get things working with a tiny workaround.

As you may know, the Angular Service Worker gets auto-generated on build time and outputs the ngsw-worker.js in your /dist folder.

On the other hand, following Angular Fire documentation, we created a service worker (firebase-messaging-sw.js) that will just hang out in the background (even after the ionic app has been closed by the user) waiting to detect new messages to notify the user.

importScripts('https://www.gstatic.com/firebasejs/5.4.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/5.4.1/firebase-messaging.js');

firebase.initializeApp({
'messagingSenderId': ‘YOUR_SENDER_ID'
});

const messaging = firebase.messaging();

You can find your project specific sender-id under your Firebase project Cloud Messaging Settings.

To solve the restriction that forces us to install just one worker per application, we created a simple worker that combines the previous two (combined-sw.js).

importScripts('ngsw-worker.js');
importScripts('firebase-messaging-sw.js');

Finally, update your app.module.ts and register that combined worker instead:

ServiceWorkerModule.register('combined-sw.js', { enabled: environment.production })

Keep in mind that you will also need to add the two new service workers we manually added to the project inside the production build section of your angular.json file

"assets": [
...
  "src/combined-sw.js",
  "src/firebase-messaging-sw.js"
]

This will ensure those files get copied to the output folder when building your project.

Adding required Push Notifications configuration to the Web Manifest

You will also need to add extra configuration in your web app manifest specifying the gcm_sender_id which is a hard-coded value that indicates that FCM is authorized to send messages to this app. Make sure to add the browser sender ID in your manifest.json file exactly as shown (do not change the value).

"gcm_sender_id": "103953800507"

Note: Please don't confuse the "browser sender ID" with the "project-specific sender ID" value shown in your Firebase project settings. The browser sender ID for the manifest.json is a fixed value, common among all FCM JavaScript clients.

The project specific sender-id is the one we used in the previous step inside the firebase-messaging-sw.js file to initialize the firebase app.

Configure "VAPID" keys with FCM

Wait, what is VAPID?

VAPID stands for Voluntary Application Server Identification for Web Push protocol, and is a way to let publishers (like FCM to optionally identify themselves. A VAPID key is a cryptographic public/private key pair that is used in the following way:

  • The public key is used as a unique server identifier for subscribing the user to notifications sent by that server
  • The private key needs to be kept secret (unlike the public key) and its used by the application server to sign messages, before sending them to the Push Service for delivery

To subscribe your Ionic framework app to push notifications, you need to associate a pair of keys with your Firebase project. To do so, open the Cloud Messaging tab of the Firebase console Settings page and scroll to the Web configuration section. In the Web Push certificates tab, click Generate Key Pair.

Finally, the Firebase console displays a notice that the key pair was generated, and displays the public key string and date added.

ionic PWA push notifications

Requesting users permission to send them notifications

Now that we have the Firebase Messaging Service Worker setup and installed, it's time to ask the user if he wants to receive notifications from our App. By default, the browser will popup a UI for you, but it's highly recommend to ask the user for permission with a custom UI and only ask when it makes sense. If you blindly ask for permissions you have an extremely high chance of being rejected.

This is why we are not going to request push notifications permissions immediately after our Ionic PWA loads. We will add a button to trigger the permissions request.

home.page.html

<button (click)="requestPushNotificationsPermission()">
Enable notifications!
</button>

We will use the AngularFireMessaging service to request user permission.

home.page.ts

import { Component } from '@angular/core';
import { AngularFireMessaging } from '@angular/fire/messaging';

@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {

constructor(private afMessaging: AngularFireMessaging) { }

  requestPushNotificationsPermission() {
    this.afMessaging.requestToken
      .subscribe(
        (token) => {
          console.log('Permission granted! Save to the server!', token);
        },
        (error) => {
          console.error(error);
        }
      );
  }
}

Notice that the AngularFireMessaging service requestToken function combines requesting permission and getting tokens. We need to get a token for each user in order to send them notifications.

Sending push notifications from our Ionic PWA

As we mentioned earlier, there are many ways you can send notifications to users from an Ionic progressive web app.

For simplicity, we will just test everything is working by hitting Firebase Cloud Messaging directly using cURL.

Go to your terminal console and run:

$ curl -X POST \
https://fcm.googleapis.com/fcm/send \
-H 'Authorization: key=YOUR-SERVER-KEY' \
-H 'Content-Type: application/json' \
-d '{
"notification": {
  "title": "Hello World",
  "body": "This is Message from Admin"
},
  "to" : "USER-REQUESTED-TOKEN"
}'

You can find YOUR-SERVER-KEY under your Firebase project Cloud Messaging Settings (explained in step 2).

Full Progressive Web App with Ionic

Known Issues

Angular app Service Workers issues on browsers based on Chromium < 60

While testing this ionic example PWA on Chrome browser v58 in Android I got issues with repeated visits to the site. After browsing for a solution, I found that it was a @angular/service-worker bug (issue 1, issue 2).

Luckily after upgrading Chrome on Android everything started working OK.

Notifications not working if permissions are granted inside the PWA

If the user grants permission to push notifications within Chrome browser in Android, then the notifications work ok. But if the user grants permissions inside the installed PWA, then the notifications don't arrive.

We won't be adding much details to this Ionic PWA example, just some minor UI tweaks and some user interaction improvements related to the progressive web app install banner.

App logo and miscellaneous data

By default, the @angular/pwa package creates a manifest.json file with the Angular logo as the app icon. Be sure to update the manifest to use the correct app name and also replace the icons with your own.

When creating your PWA icon, make sure to read this post which explains how to create adaptive icons for your PWAs using maskable icons. Maskable icons are a new icon format that give you more control and let your PWA use adaptive icons. If you supply a maskable icon, your icon can fill up the entire shape and look great on all Android devices.

PWA Install Banner

Just like we did with the push notifications permissions prompt, it's highly recommended to show the app install banner to the user when it really makes sense.

By default, the browser (if it has support for service workers) will prompt the user to install the app as soon as the user starts interacting with the page.

Ionic PWA install banner
progressive web app install banner
add pwa to homescreeen

To achieve this, we need to prevent the event that the browser fires and save a reference to that event for later:

window.addEventListener('beforeinstallprompt', (e) => {
  console.log('beforeinstallprompt Event fired');
  // Prevent Chrome 67 and earlier from automatically showing the prompt
  e.preventDefault();
  // Stash the event so it can be triggered later.
  this.deferredPrompt = e;
});

Once we have the reference to the event it's easy to trigger the install prompt at any time:

showInstallBanner() {
  if (this.deferredPrompt !== undefined && this.deferredPrompt !== null) {
    // Show the prompt
    this.deferredPrompt.prompt();
    // Wait for the user to respond to the prompt
    this.deferredPrompt.userChoice
    .then((choiceResult) => {
      if (choiceResult.outcome === 'accepted') {
        console.log('User accepted the A2HS prompt');
      } else {
        console.log('User dismissed the A2HS prompt');
      }
      // We no longer need the prompt.  Clear it up.
      this.deferredPrompt = null;
    });
  }
}

Finally, let's add a simple "Install the app" button and bind it to that method.

More meaningful app pages

Let's make our Ionic PWA more appealing than the Ionic starter by adding some pages to showcase the ten principles of Progressive Web Apps mentioned earlier.

progressive web apps in ionic
progressive web app example
Ionic PWA example app

Room for improvements

Although we achieved a full featured progressive web app, there are plenty of details we can work on. In this detailed checklist you can find advanced checks to enhance the performance and usability of your PWA and take it from a baseline to exemplary experience.

Two of the most important things that you should consider to improve the app is adding both server side rendering and lazy loading capabilities. These will help you achieve better user perceived performance as your app will have faster interaction times.

Most browsers fully support the underlying technologies that enable progressive web apps, and there are others like Safari for iOS and macOS that have been silently adding basic support for Progressive Web Apps. Check this in-depth post to learn what you can and can't do currently in terms of PWAs in iOS.

Capabilities of PWAs on iOS

With the Web Platform on iOS you can access:

  • Geolocation
  • Sensors (Magnetometer, Accelerometer, Gyroscope)
  • Camera
  • Audio output
  • Speech Synthesis (with headsets connected only)
  • Apple Pay
  • WebAssembly, WebRTC, WebGL as well as many other experimental features under a flag.

What PWAs can do on Android and not on iOS

  • On Android you can store more than 50 Mb
  • Android doesn't delete the files if you don't use the app, but it can delete the files under storage pressure. Also, if installed or used a lot by the user the PWA can request Persistent Storage
  • Bluetooth access for BLE devices
  • Web Share for accessing native share dialog
  • Speech Recognition
  • Background Sync and Web Push Notifications
  • Web App Banner to invite the user to install the app
  • You can customize (a little bit) the splash screen and the orientations you want
  • With WebAPK and Chrome, users can't install more than one instance of a PWA
  • With WebAPK and Chrome, the PWAs appears under Settings and you can see data usage; on iOS everything appears under Safari
  • With WebAPK and Chrome, the PWA manages intents for its URL, so if you get a link to the PWA, it will be opened in standalone mode and not within the browser's window.
ionic templates

On this post we went through the definition of PWAs, also we deep dived into the business details of PWAs and their benefits. Then, we got more technical discussing the different paths your can follow to implement your PWA with Ionic. Particularly, on this post we followed the Ionic Angular way.

Then, we saw the step by step process of building an Ionic Angular Application with PWA capabilities. We used Lighthouse to audit our progress and reached a 100/100 Ionic PWA. Cheers to that!

Finally, we went a step further and carefully explained how to add Push Notifications to our Ionic PWA using Firebase Cloud Messaging (FCM).

I really hope you enjoyed this extensive post about Progressive Web Apps with Ionic Framework and Firebase. It was really a pleasure to share my knowledge with you, I hope you feel the same and please let me know your feedback in the comments below.

As I mentioned before, I do believe PWAs are the future (or should I say the present?). Stay tuned as I will be updating this post as new features become available and more Ionic tutorials so subscribe to our newsletter to keep learning Ionic Framework!

If you want to discover all the possibilities the new Ionic Navigation brings and also learn some usability tricks we can add to our Ionic Framework apps to make them look even better you need to read Ionic Navigation & Routing: The Ultimate Guide.

Also, if you want to start building a feature complete PWA with Ionic and Angular but don't know where to start, you can get Ionic 6 Full Starter App and save yourself hundreds of ours of design and development.