Progressive Web Apps with PokeAPI and Deploy using Firebase
How to Create and Deploy a Simple Progressive Web Apps to Firebase?
Hi all, now I want to share what I’ve got after finishing course for building PWA. Actually, there are plenty article out there that already introduce PWA. But I still write this because I get excited with it. I write this based on my experience, so correct me if something wrong with this article 😅
The first thing what we should know is "what is PWA". PWA is a web application that combines features of a modern browser with the mobile experience. With PWA, there is a lot of advantages, such as run the app in offline mode, added the app to the screen directly, accessible via URLs, and etc. Those with all the advantages, PWA also have some disadvantages, like not supported yet for all the browser, not available through store app, etc. But, with the advantages offered by PWA, there is no way we don’t try it.
When we build PWA, there is some component that we’ve to use.
Service worker is a script that runs in the background app and separates from the web page and will allow us to use some feature that doesn’t need user interaction. Service worker will act as a proxy when a user makes a request to our web and will decide whether the request will continue to the server or will use the data that have been stored before (Read more here).
Cache is local storage used by a browser to save some resource when we visit some page. If we visit the page for the second time, the page will load the resource from the cache.
Web App Manifest
Web app manifest is a JSON that contain metadata about our application and tell the browser how the app should behave. (Read more here).
Fetch API is an interface that allows us to access and manipulate resource across the network. (Read more here).
Push notifications are a way to notify users of important events even if they are not using the application at the moment. (Read more here)
App shell is a user interface component that will be used like header, sidebar, footer. It will cache first and display the same content every time user visit (consistency). Because we save the app shell in a cache, we don’t need to request it to the server. (Read more here).
IndexedDB is a built-in database in our browser. And IndexedDB is NoSQL, which means that we cannot do a query using SQL syntax. (Read more here).
Now, let’s build our own PWA. What will we try to build is a simple app about pokemon. We will be using pokemon API for this project (PokeAPI). We also will use Materialize CSS (download here). You can use another CSS framework if you want. Extract the .zip file into your project folder. Your project folder should be like here 👇
For the first step, create
index.html in the root folder. Make the HTML structure, and fill
<body> tag with :
After that, before
</body> tag, add this 👇
What we do here is, check if object navigator already exists in our browser. If the navigator doesn’t exist, that means our browser not supported yet.
Then, we register our
service-worker.js using method
navigator.serviceWorker.register(). Now, let’s create a file
service-worker.js and fill it with this code 👇
What we do here is first we give the cache name with a variable
CACHE_NAME. Then, we add files that we want to cache in
urlsToCache. After that, we add an event listener for
install and will call when the service worker registration success. We open the cache first with
caches.open() and add our
urlsToCache file into the cache using
cache.addAll(). We can check our cache in our Cache Storage whether it succeeds or not in DevTools tab Application.
Next, let’s add this code to use the asset from our cache.
What we do here is, first, we check if the request equals with the asset in our cache. If the request matches, it will return asset form the cache. If it’s not, it will request the asset to the server. Then, let’s make our app able to add to home screen. Add this code in our
<head> element 👇
Then, create a file
manifest.json in the root folder and add this code 👇
To ensure that our manifest already set up correctly, go to the Manifest tab on the Application panel of Chrome DevTools. After all, we can run our app by using the Web Server for Chrome and go to the URL.
We’ve made all the component that we need, and now, let’s add the data. As I mentioned before, we will be using PokeAPI. You can check and try it first.
The first thing we’re gonna do is create a file
api.js in the
js folder. This file will handle when our application interacts with the PokeAPI. Add this code in the
What we do here is, first, we make the variable
base_url that contains the URL for the API. Then, we create a function
getAllPokemon() to get all the data pokemon from the API. In this function, we also render the data to the HTML using
innerHTML and save the response to the cache. After that, let’s call the function in
index.html by adding this code 👇
Don’t forget to call the
<script src="js/api.js"></script> and add the file to
And when you run the app, you should get a result like below. Cool right lol.
Then, let’s create
detailPokemon.html in the root folder, to display the detail of the pokemon. You can copy the
index.html and change the code inside the
<script> with this code 👇
Now, let’s create the function in
api.js with code below 👇
This function will get a response from the API about the pokemon by the name, and we will display the data in the HTML. Until here, we should be able to see all the pokemon list in
index.html and able to see the detail for each pokemon in
detailPokemon.html like the image below. You can customize the detail as you wish and make better than mine (I’m bad at design 😅).
Now, let’s make some improvement 😆. What we gonna do is, we will make a page for our favorite pokemon, and able to use notification. We will use IndexedDB to save our favorite pokemon.
First, let’s download the library here. Extract the file, and copy the
idb.js file into the
js folder. Don’t forget to add it in
urlsToCache variable to cache the file first. Don’t forget to call the
<script src="js/idb.js"></script> before
</body> tag. Now, let’s add fab in the
detailPokemon.html to trigger function and save the pokemon to our favorite list. In the button, we add
onclick event and call
addPokemon() to trigger the function for saving data to the IndexedDB.
Let’s create a file
js folder, and don’t forget to add the file in
sevice-worker.js like before. This file will handle our database operation. First, add this code like below 👇
What we do here is, first, we use
idb.open() to return a Promise that contains database object which we will use it for interaction to IndexedDB. If the database doesn’t exist yet, IndexedDB will create a new database. We will use
id as a primary key using
keypath. After that, add this code in
addPokemon() function like below 👇
What we do here is, after fetching the data from API we will save it to the database with
store.put()using transaction. If transaction success, it will redirect to
fav-pokemon.html Yup, we don’t have
fav-pokemon.html now, but we will add it later. Let’s finish the function first.
Now, we’re able to store the pokemon to our favorite list in the database. Let’s make another function to get all our favorite pokemon with this code 👇
store.getAll() function, we will get all the data from the database and will display it in the HTML using
innerHTML. Next, we will create the
deletePokemon() function with this code 👇
In the code above, we will able to delete the pokemon from the database using
id as the parameter. If the transaction success, it will redirect us to
index.html. Now, our
db.js is ready and let’s create
fav-pokemon.html in our root folder, and should call the
Next, let’s link
fav-pokemon.html to our app like below 👇
And… there it is 😙 Our app should able to :
- Show all pokemon from API
- Go to detail pokemon
- Add pokemon to favorite list
- Remove pokemon from favorite list
For the last touch, let’s make some notification when we add the pokemon to our favorite list, and also when we remove it. First, add this code in
This code will check whether the browser supports notification or not. If notification allowed, we will able to receive notification from this app. And last, add this code in
Notification for addPokemon()
Notification for deletePokemon()
Cool right? Now, we will deploy our app using firebase 🤩
First, we need
npm in our environment. (Check out here). Then, let’s start by type this command in your terminal.
$ npm install -g firebase-tools
Next, let’s create our firebase account in https://console.firebase.google.com/
Then, follow the step until you got popup Your new project is ready. Open your terminal and type
$ firebase login.
By this command, you will get window browser to verify your Google account. If the login process succeeds, you will success message like below.
Now, we can go to our project directory and type
$ firebase init
It will show us some options like below.
Go select Hosting: Configure and deploy Firebase Hosting sites.
And then we will get the option like below. If you don’t create the project in the firebase yet, choose [create a new project], and create the project.
After that, you will get a question like below, Just hit enter for the first question, and type N for the second question.
Then, it will generate file
.firebashrc. And you will get this message if it succeeds.
Then, we can use the command :
$ firebase use --add
This command will add our project to the firebase and select the destination project in the firebase.
You will be asked to make an alias name for the project, and you can fill it as you wish. I make my own with
Before we deploy our app, we need to change something in our
firebase.json and should look like this.
What we do here is to make the app will go to
index.html when the app launched.
And for the finishing step, just type
$ firebase deploy
and BOOM 💥💥💥. Our project already deployed. We can access it through the Hosting URL.
Yash 🎉 🎉 🎉 That’s our app. Hope this article helps you. If you have opinion or correction, please kindly tell me. See you in another article 👋
You can access the full code in my repo here