SlideShare a Scribd company logo
Let’s Keep in Touch:
Building a Website that works without Internet
Using Angular, Service Workers and Firebase
Tomiwa Ademidun
1
What Are We Going To Build
● A Progressive Web App that works without the internet (offline-first)
● The Website: demo.atila.ca
● Theory on how service workers work
● Application: Live Practical Tutorial on how to build offline-first web apps
● Bonus: Rant on Why this is awesome
2
Different Formats of this Talk
This tutorial is available as a...
1. Slideshow
2. Video
3. Blog
4. Podcast
5. Source Code
3
About Me
● Tomiwa Ademidun, software engineering and
business student at Ivey Business school, Canada
● Currently on year off to start edtech startup atila.ca,
automatically find and apply to scholarships in one
click.
● Founder of software engineering studio,
tech.atila.ca
● Software Engineering Intern @ Properly, Employee
#5@tomiwa1a
4
Theory
What’s an offline first-web
app???
What’s a service worker???
Why should I care???
Is there free food after
this???
5
What does this diagram represent?
6
Alibaba, Amazon, Instagram etc. are very
powerful websites, but have one flaw
● Alibaba $25 billion in sales in one day (singles day)
● 40% of cloud computing clients Amazon Web Services Including: Apple,
Netflix and CIA
● 2.2 Billion people use Facebook every month, 700 million Instagram
● But without wifi, the entire site is unusable
7
No Internet, No Fun
With internet Without internet 8
Atila is not quite as large, but its always
there for you
● Humble, little atila.ca has much fewer users
● But with or without internet you can still use atila.ca
● Google Drive also does this really well
9
No Internet, No Problem
With internet Without internet 10
No Internet, No Problem
With internet Without internet: metaphorically “Raise your hand” if you
knew you could use Google Drive without internet? 11
What does this diagram represent?
Millions of Daily Users Works Offline 12
What is a Service Worker?
● A proxy/messenger between your
browser and the internet
● When your web app asks for
resources (images, html files, json API
etc.) the service worker gets it for you
without asking internet
● In literal terms, it is a javascript file
that gets shipped along with the rest
of your app
13
● The service worker intercepts each request your browser makes and tries
to fulfill the request itself
● First it checks its local cache to see if it has the resources you need
● If it doesn’t:
a. Goes to the network and asks for the resources
b. Saves resources to its local cache
c. Serves you the resources from its cache
● Works both with and without internet
a. Faster connections even with internet
How Does It Work?
14
Enough Talking, Let’s Build it!
15
Prerequisites
● Node.js® and npm
○ Make sure you have node 8.X or greater (node -v ) and npm 5.x or greater ( npm -v)
● Globally install Angular CLI
○ npm install -g @angular/cli
● Google Chrome Browser (optional, but recommended)
● Google Account (optional if you want to deploy to Firebase)
16
Clone the atila web app
● Go to https://github.com/atilatech/atila-web-app
● Clone the demo.atila.ca web app from Github: atila-web-app
○ Checkout the pwa-tutorial branch: git checkout pwa-tutorial
○ Checkout the tutorial start commit: git checkout pwa-tutorial-0.0
○ Install npm modules: npm install
○ Start the app!” ng serve -o
○ If you get an No NgModule error. Go to any .ts file and put a space
■ Very weird bug! Learn More
17
Install the Service Worker Module
1. Install the @angular/serviceworker module:
a. npm install @angular/service-worker@5.2.11 --save
2. Tell angular-cli to build project with service worker:
a. ng set apps.0.serviceWorker=true
3. Configure your service worker in ngsw-config.json
4. Add a manifest.json file and reference it in index.html
Further Reading:
● Transforming an existing Angular application into a Progressive Web App
● Turning an Angular 6 app into a Progressive Web App
18
Not Just Copy Paste, What does
it Mean
Starting Git Tag: pwa-tutorial-0.0
19
Install the Service Worker Module: #3e66c3a
● npm install @angular/service-worker@5.2.11
--save:
○ This module contains the service worker objects
that we will be using in the next step
● Ng set apps[0].serviceWorker=true:
○ Tell angular CLI to automatically produce a
javascript file that contains the code for the
service worker, when building project explained
in next step
20
Service Worker Configuration
● This tells your service worker, exactly what files it should be saving
and how it should be saving them:
● assetGroups: files that are included as part of the app,
○ When the app updates, these resources update as well
● dataGroups: external resources not versioned with app
● Install Mode: What caching strategy to use when first seeing this file
● UpdateMode: What caching strategy to use when updating the file,
after we’ve already installed it
● Caching strategy:
○ Prefetch: Save these files before we even ask for it
○ Lazy: Save these files only after they’ve been requested at least
once
21
Further Reading:
● https://angular.io/guide/service-worker-config
Github Gist / Github Diff
Manifest.json
● This is what turns your app from a web
app to a progressive web app
○ Basically a web app that behaves like a
native mobile app
● Allows users to install your app to home
screen
● Add the home screen icon
● Reference it in index.html
22
{
"name": "Atila",
"short_name": "Atila",
"start_url": "index.html",
"display": "standalone",
"icons": [{
"src":
"assets/img/favicon-bg.png",
"sizes": "512x512",
"type": "image/png"
}],
"background_color": "#194f87",
"theme_color": "#194f87"
}Further Reading:
● Google Web Fundamentals: Add to Home Screen
● Google Web Fundamentals: Web App Manifest
Register the Service Worker: #d2b186f
● Tell app our service worker exists
● Add the service worker module to
app.module.ts
● Register the service worker in main.ts
○ Check if the browser has service worker
support
// src/main.ts
if ('serviceWorker' in navigator &&
environment.production) {
console.log("Service Worker in main.ts");
window.addEventListener('load', () => {
console.log("on page Load Service Worker in main.ts");
navigator.serviceWorker.register('/ngsw-worker.js', {
scope: '/',
})
.then(registration => {
console.log("Service Worker registration completed
main.ts", registration);
});
});
23
// src/app.module.ts
import {ServiceWorkerModule} from '@angular/service-worker';
…
Imports: [
…,
ServiceWorkerModule.register('/ngsw-worker.js', {enabled:
environment.production}),]
Part 1a: Build The Service Worker
24
The service Worker Output
● Build your app
○ ng build --prod
● Let’s look at the additional files
that were produced in dist/
1. Ngsw.json
2. ngsw-worker.js
25
The service Worker Output: ngsw.json
● This file was generated based on the
instructions from the ngsw-config.json
files
● It tells your serviceworker to cache any of
the files in this list
● Caching strategy:
○ Prefetch: Save these files before we even
ask for it
○ Lazy: Save these files only after they’ve
been requested at least once
26
The service Worker Output: ngsw-worker.js
● This file is literally the service worker
● We registered it earlier in our main.ts file
● A plain javascript file containing the code
and logic for how your service worker
registers and caches your service worker
to database
● If you’re up for a challenge, try looking
through the code and see if you can
understand what is happening
● Add Screenshot of ngsw.js
27
Part 1b: Testing The Service
Worker
Github Commit: #2001441
28
Creating A Mini Server
● Service workers are used in an offline
contexts, so we need a server that can
simulate offline environments
● Install npm http server
○ Npm install
http-server@0.11.1
--save-dev
● Build and Run the server
○ ng build --prod (optional)
○ http-server -p 8080 -c-1
dist
29
Inspecting the Server Requests
● Visit Chrome Network tab in
devtools
○ Do this before going to
localhost!
○ Open a new tab
○ Right click somewhere
blank on screen
○ Inspect > go to Network
Tab
● Open http://localhost:8080/
30
● Note that there is no wi-fi in top right
● See console: The external network resources
fail with 504 but our files are succesful (200)
Where are the Files Being Saved?
● Open the application tab in Devtools and
you will see local cache section
● This is the “database” where the service
workers are saving your files
● That’s it! You now have a simple but fully
functional offline first web app. Continue
to part 2 for adding more cool features
31
Further Reading:
● Angular University: Angular Service Workers
Part 2: Saving External Data
Part 1 Git Tag: pwa-tutorial-0.1
32
Why are None of My APIs Working?
● When you try to click on a link, you will
notice a server error
● Your service worker doesn’t have those
APIs in your database, but we can add it
● Pop Quiz! If we want to tell our service
worker to cache a new type of file where
should we put the code to do so:
a. Manifest.json
b. Ngsw-config.json
c. app.module.ts
33
Saving External API calls: Configuration
● Now we will configure our
ngsw-config.json to cache external API
urls as well
● Two caching options
a. Freshness: Go to the network first, if
missing, go to the
b. Performance: Go the cache first, then go to
network
34Github Diff
Further Reading:
● https://angular.io/guide/service-worker-config
Saving External API calls: #8593ada
● You might need to use a seperate URL that allows your app to access it via CORS
● We will use a special JSON service to simulate (“mock”) our blog API
○ Since We don’t have permission to use official Atila API’s
● Change ScholarshipService.getPaginatedScholarships:
○ Go to src/app/_service/scholarship.service.ts#L47
○ Change: this.http.post(`${this.scholarshipsPreviewUrl}?page=${page}/`,
form_data)
○ To: this.http.get(`https://api.myjson.com/bins/dx1dc`)
● Change BlogPostService.getBySlug:
○ Go to src/app/_service/blog-post.service.ts#L25
○ Change: this.http.get(`${this.blogUrl}blog/${username}/${slug}/`)
○ To: this.http.get(`https://api.myjson.com/bins/v5ow0`)
35
Part 3: Notify Users of New Updates
Part 2 Git Tag: pwa-tutorial-0.2
36
Notifying of New Updates
● When a new version is available from
network, service worker still serves the old
version in cache to save time
● Add your profile to team page
○ src/app/team/team.component.ts
○ Add your image and some information
in the team data array
● Rebuild project and restart server
● You’ll notice that your profile doesn’t
appear yet
37
Notify Users of New Updates: Snackbar
● Rebuild project and restart server
● We can add a snackbar to notify user of
new updates
○ npm install
@angular/material@5.1.1 --save
(you might already have this)
● Then we create swUpdate to listen for
updates from the SW and update if a new
version is available.Github Diff
● Rebuild and reserve your application (see
slide 24)
38
Part 4: Deployment
Part 3 Git Tag: pwa-tutorial-0.3
39
Deploy to Firebase Hosting
● To truly see effect of service worker we should probably deploy it to a real
website:
Deployment Prerequisites:
1. Create a google account
2. A firebase account and a firebase project
3. install firebase tools globally: npm install -g firebase-tools@4.2.0
4. Log in to firebase: firebase login
40Further Reading: Angular Firebase - Deploying an Angular App to Firebase
Deploy to Firebase Hosting
1. Initialize Firebase Repo: firebase init
2. Choose the following settings:
○ Choose hosting as the project type
○ Change public folder to dist/
○ Configure as a single page app
○ Overwrite idnex.html? NO
3. Deploy! Firebase deploy
4. Visit the url in the command line output to
see your app
41
The Future with Service Workers
Part 4 (final) Git Tag: pwa-tutorial-0.4
42
The Future is Awesome
● Imagine if you could read your favorite NY Times articles or
● Read your twitter “while you were gone” tweets
● While on the plane!
● Imagine if you could save your Amazon shopping cart and read the product
reviews while on train to work in morning
● The next 1 billion users of internet have poor internet connection: think of
how this benefits them
● With service workers all this and more is possible
43
Mobile vs. Web
● With all these features and push notifications (story for another day), why
make a native mobile app?
● See this article for why startups and companies should consider web apps:
○ Tl:dr native apps are hard because of: app store gatekeepers, supporting 2 different
platforms (ios, Android), no one wants to download another app,
44
What this Means for You
● If starting a company, really consider if building a native mobile app is
worth it or is a PWA a better choice
● When building your web app don’t let lack of internet be a constraint, it
should be a feature!
○ Hard to compete for users attention when there is internet
○ Imagine if you are one of the few apps that works when there is no internet
45
Resources
● Angular Official Service Worker Documentation
● Angular University: Angular Service Workers
● Add Service Worker to Existing Angular App
● Angular Firebase - Deploying an Angular App to Firebase
46
Thanks For Watching
47

More Related Content

How to build a website that works without internet using angular, service workers and firebase let's keep in touch

  • 1. Let’s Keep in Touch: Building a Website that works without Internet Using Angular, Service Workers and Firebase Tomiwa Ademidun 1
  • 2. What Are We Going To Build ● A Progressive Web App that works without the internet (offline-first) ● The Website: demo.atila.ca ● Theory on how service workers work ● Application: Live Practical Tutorial on how to build offline-first web apps ● Bonus: Rant on Why this is awesome 2
  • 3. Different Formats of this Talk This tutorial is available as a... 1. Slideshow 2. Video 3. Blog 4. Podcast 5. Source Code 3
  • 4. About Me ● Tomiwa Ademidun, software engineering and business student at Ivey Business school, Canada ● Currently on year off to start edtech startup atila.ca, automatically find and apply to scholarships in one click. ● Founder of software engineering studio, tech.atila.ca ● Software Engineering Intern @ Properly, Employee #5@tomiwa1a 4
  • 5. Theory What’s an offline first-web app??? What’s a service worker??? Why should I care??? Is there free food after this??? 5
  • 6. What does this diagram represent? 6
  • 7. Alibaba, Amazon, Instagram etc. are very powerful websites, but have one flaw ● Alibaba $25 billion in sales in one day (singles day) ● 40% of cloud computing clients Amazon Web Services Including: Apple, Netflix and CIA ● 2.2 Billion people use Facebook every month, 700 million Instagram ● But without wifi, the entire site is unusable 7
  • 8. No Internet, No Fun With internet Without internet 8
  • 9. Atila is not quite as large, but its always there for you ● Humble, little atila.ca has much fewer users ● But with or without internet you can still use atila.ca ● Google Drive also does this really well 9
  • 10. No Internet, No Problem With internet Without internet 10
  • 11. No Internet, No Problem With internet Without internet: metaphorically “Raise your hand” if you knew you could use Google Drive without internet? 11
  • 12. What does this diagram represent? Millions of Daily Users Works Offline 12
  • 13. What is a Service Worker? ● A proxy/messenger between your browser and the internet ● When your web app asks for resources (images, html files, json API etc.) the service worker gets it for you without asking internet ● In literal terms, it is a javascript file that gets shipped along with the rest of your app 13
  • 14. ● The service worker intercepts each request your browser makes and tries to fulfill the request itself ● First it checks its local cache to see if it has the resources you need ● If it doesn’t: a. Goes to the network and asks for the resources b. Saves resources to its local cache c. Serves you the resources from its cache ● Works both with and without internet a. Faster connections even with internet How Does It Work? 14
  • 15. Enough Talking, Let’s Build it! 15
  • 16. Prerequisites ● Node.js® and npm ○ Make sure you have node 8.X or greater (node -v ) and npm 5.x or greater ( npm -v) ● Globally install Angular CLI ○ npm install -g @angular/cli ● Google Chrome Browser (optional, but recommended) ● Google Account (optional if you want to deploy to Firebase) 16
  • 17. Clone the atila web app ● Go to https://github.com/atilatech/atila-web-app ● Clone the demo.atila.ca web app from Github: atila-web-app ○ Checkout the pwa-tutorial branch: git checkout pwa-tutorial ○ Checkout the tutorial start commit: git checkout pwa-tutorial-0.0 ○ Install npm modules: npm install ○ Start the app!” ng serve -o ○ If you get an No NgModule error. Go to any .ts file and put a space ■ Very weird bug! Learn More 17
  • 18. Install the Service Worker Module 1. Install the @angular/serviceworker module: a. npm install @angular/service-worker@5.2.11 --save 2. Tell angular-cli to build project with service worker: a. ng set apps.0.serviceWorker=true 3. Configure your service worker in ngsw-config.json 4. Add a manifest.json file and reference it in index.html Further Reading: ● Transforming an existing Angular application into a Progressive Web App ● Turning an Angular 6 app into a Progressive Web App 18
  • 19. Not Just Copy Paste, What does it Mean Starting Git Tag: pwa-tutorial-0.0 19
  • 20. Install the Service Worker Module: #3e66c3a ● npm install @angular/service-worker@5.2.11 --save: ○ This module contains the service worker objects that we will be using in the next step ● Ng set apps[0].serviceWorker=true: ○ Tell angular CLI to automatically produce a javascript file that contains the code for the service worker, when building project explained in next step 20
  • 21. Service Worker Configuration ● This tells your service worker, exactly what files it should be saving and how it should be saving them: ● assetGroups: files that are included as part of the app, ○ When the app updates, these resources update as well ● dataGroups: external resources not versioned with app ● Install Mode: What caching strategy to use when first seeing this file ● UpdateMode: What caching strategy to use when updating the file, after we’ve already installed it ● Caching strategy: ○ Prefetch: Save these files before we even ask for it ○ Lazy: Save these files only after they’ve been requested at least once 21 Further Reading: ● https://angular.io/guide/service-worker-config Github Gist / Github Diff
  • 22. Manifest.json ● This is what turns your app from a web app to a progressive web app ○ Basically a web app that behaves like a native mobile app ● Allows users to install your app to home screen ● Add the home screen icon ● Reference it in index.html 22 { "name": "Atila", "short_name": "Atila", "start_url": "index.html", "display": "standalone", "icons": [{ "src": "assets/img/favicon-bg.png", "sizes": "512x512", "type": "image/png" }], "background_color": "#194f87", "theme_color": "#194f87" }Further Reading: ● Google Web Fundamentals: Add to Home Screen ● Google Web Fundamentals: Web App Manifest
  • 23. Register the Service Worker: #d2b186f ● Tell app our service worker exists ● Add the service worker module to app.module.ts ● Register the service worker in main.ts ○ Check if the browser has service worker support // src/main.ts if ('serviceWorker' in navigator && environment.production) { console.log("Service Worker in main.ts"); window.addEventListener('load', () => { console.log("on page Load Service Worker in main.ts"); navigator.serviceWorker.register('/ngsw-worker.js', { scope: '/', }) .then(registration => { console.log("Service Worker registration completed main.ts", registration); }); }); 23 // src/app.module.ts import {ServiceWorkerModule} from '@angular/service-worker'; … Imports: [ …, ServiceWorkerModule.register('/ngsw-worker.js', {enabled: environment.production}),]
  • 24. Part 1a: Build The Service Worker 24
  • 25. The service Worker Output ● Build your app ○ ng build --prod ● Let’s look at the additional files that were produced in dist/ 1. Ngsw.json 2. ngsw-worker.js 25
  • 26. The service Worker Output: ngsw.json ● This file was generated based on the instructions from the ngsw-config.json files ● It tells your serviceworker to cache any of the files in this list ● Caching strategy: ○ Prefetch: Save these files before we even ask for it ○ Lazy: Save these files only after they’ve been requested at least once 26
  • 27. The service Worker Output: ngsw-worker.js ● This file is literally the service worker ● We registered it earlier in our main.ts file ● A plain javascript file containing the code and logic for how your service worker registers and caches your service worker to database ● If you’re up for a challenge, try looking through the code and see if you can understand what is happening ● Add Screenshot of ngsw.js 27
  • 28. Part 1b: Testing The Service Worker Github Commit: #2001441 28
  • 29. Creating A Mini Server ● Service workers are used in an offline contexts, so we need a server that can simulate offline environments ● Install npm http server ○ Npm install http-server@0.11.1 --save-dev ● Build and Run the server ○ ng build --prod (optional) ○ http-server -p 8080 -c-1 dist 29
  • 30. Inspecting the Server Requests ● Visit Chrome Network tab in devtools ○ Do this before going to localhost! ○ Open a new tab ○ Right click somewhere blank on screen ○ Inspect > go to Network Tab ● Open http://localhost:8080/ 30 ● Note that there is no wi-fi in top right ● See console: The external network resources fail with 504 but our files are succesful (200)
  • 31. Where are the Files Being Saved? ● Open the application tab in Devtools and you will see local cache section ● This is the “database” where the service workers are saving your files ● That’s it! You now have a simple but fully functional offline first web app. Continue to part 2 for adding more cool features 31 Further Reading: ● Angular University: Angular Service Workers
  • 32. Part 2: Saving External Data Part 1 Git Tag: pwa-tutorial-0.1 32
  • 33. Why are None of My APIs Working? ● When you try to click on a link, you will notice a server error ● Your service worker doesn’t have those APIs in your database, but we can add it ● Pop Quiz! If we want to tell our service worker to cache a new type of file where should we put the code to do so: a. Manifest.json b. Ngsw-config.json c. app.module.ts 33
  • 34. Saving External API calls: Configuration ● Now we will configure our ngsw-config.json to cache external API urls as well ● Two caching options a. Freshness: Go to the network first, if missing, go to the b. Performance: Go the cache first, then go to network 34Github Diff Further Reading: ● https://angular.io/guide/service-worker-config
  • 35. Saving External API calls: #8593ada ● You might need to use a seperate URL that allows your app to access it via CORS ● We will use a special JSON service to simulate (“mock”) our blog API ○ Since We don’t have permission to use official Atila API’s ● Change ScholarshipService.getPaginatedScholarships: ○ Go to src/app/_service/scholarship.service.ts#L47 ○ Change: this.http.post(`${this.scholarshipsPreviewUrl}?page=${page}/`, form_data) ○ To: this.http.get(`https://api.myjson.com/bins/dx1dc`) ● Change BlogPostService.getBySlug: ○ Go to src/app/_service/blog-post.service.ts#L25 ○ Change: this.http.get(`${this.blogUrl}blog/${username}/${slug}/`) ○ To: this.http.get(`https://api.myjson.com/bins/v5ow0`) 35
  • 36. Part 3: Notify Users of New Updates Part 2 Git Tag: pwa-tutorial-0.2 36
  • 37. Notifying of New Updates ● When a new version is available from network, service worker still serves the old version in cache to save time ● Add your profile to team page ○ src/app/team/team.component.ts ○ Add your image and some information in the team data array ● Rebuild project and restart server ● You’ll notice that your profile doesn’t appear yet 37
  • 38. Notify Users of New Updates: Snackbar ● Rebuild project and restart server ● We can add a snackbar to notify user of new updates ○ npm install @angular/material@5.1.1 --save (you might already have this) ● Then we create swUpdate to listen for updates from the SW and update if a new version is available.Github Diff ● Rebuild and reserve your application (see slide 24) 38
  • 39. Part 4: Deployment Part 3 Git Tag: pwa-tutorial-0.3 39
  • 40. Deploy to Firebase Hosting ● To truly see effect of service worker we should probably deploy it to a real website: Deployment Prerequisites: 1. Create a google account 2. A firebase account and a firebase project 3. install firebase tools globally: npm install -g firebase-tools@4.2.0 4. Log in to firebase: firebase login 40Further Reading: Angular Firebase - Deploying an Angular App to Firebase
  • 41. Deploy to Firebase Hosting 1. Initialize Firebase Repo: firebase init 2. Choose the following settings: ○ Choose hosting as the project type ○ Change public folder to dist/ ○ Configure as a single page app ○ Overwrite idnex.html? NO 3. Deploy! Firebase deploy 4. Visit the url in the command line output to see your app 41
  • 42. The Future with Service Workers Part 4 (final) Git Tag: pwa-tutorial-0.4 42
  • 43. The Future is Awesome ● Imagine if you could read your favorite NY Times articles or ● Read your twitter “while you were gone” tweets ● While on the plane! ● Imagine if you could save your Amazon shopping cart and read the product reviews while on train to work in morning ● The next 1 billion users of internet have poor internet connection: think of how this benefits them ● With service workers all this and more is possible 43
  • 44. Mobile vs. Web ● With all these features and push notifications (story for another day), why make a native mobile app? ● See this article for why startups and companies should consider web apps: ○ Tl:dr native apps are hard because of: app store gatekeepers, supporting 2 different platforms (ios, Android), no one wants to download another app, 44
  • 45. What this Means for You ● If starting a company, really consider if building a native mobile app is worth it or is a PWA a better choice ● When building your web app don’t let lack of internet be a constraint, it should be a feature! ○ Hard to compete for users attention when there is internet ○ Imagine if you are one of the few apps that works when there is no internet 45
  • 46. Resources ● Angular Official Service Worker Documentation ● Angular University: Angular Service Workers ● Add Service Worker to Existing Angular App ● Angular Firebase - Deploying an Angular App to Firebase 46