- Serve your application with offline content
- Web Push notifications
- Sync to handle offline User DML request( REST API only)
Serve your application with offline content when network is down. Serve server rendered html when network is up.
serve your application with offline caches via Fetch event ( fetch event fires each time a request is sent to the server), what we do here is tapping into the web page request, download all requested resouces used for browser to render a page and eventually store them into cache use cache api. I named as test.
self.addEventListener("fetch", (event) => {
// "fetch" hook starts
event.respondWith(
(async () => {
let cacheName = "test";
let cache;
// Try to get from the cache first
if (cacheName) {
cache = await caches.open(cacheName);
// for html I always want to get from server unless there is no network
if (event.request.url.indexOf("session=") < 0) {
const response = await cache.match(event.request);
if (response) {
return response;
}
}
}
// Then get from network
try {
const response = await fetch(event.request);
if (response.ok && cacheName) {
try {
const resClone = response.clone();
cache.put(event.request, resClone);
} catch (error) {
console.warn(error);
}
}
// Return resource from network
return response;
} catch (error) {
// for apex page where i do have cache , i serve the cache
const response = await cache.match(event.request);
if (response) {
return response;
} else {
// for apex page where i DO NOT have cache, i serve dummy html
if (event.request.mode === "navigate") {
const offlinePage =
'<div style="height:100%;text-align:center; font-size:30px;padding-top: 50%;"> Your Device Is Offline </div>';
return new Response(offlinePage, {
headers: { "Content-Type": "text/html" },
});
} else {
return new Response();
}
}
}
})()
);
});
let apex = {};
apex.sw = {};
apex.sw.CORE_CACHE_MATCHER = '#APEX_FILES#';
apex.sw.CORE_CACHE_PREFIX = "APEX-CORE-";
apex.sw.CORE_CACHE_NAME = apex.sw.CORE_CACHE_PREFIX + '#APEX_VERSION#';
apex.sw.APP_CACHE_MATCHER = "&FB_FLOW_ID./files/static/v";
apex.sw.APP_CACHE_PREFIX = "APEX-APP-&FB_FLOW_ID.-v";
apex.sw.appCacheNeedsCleanup = true;
apex.sw.cleanAPEXCaches = () => {
caches.keys().then(cacheNames => Promise.all(
cacheNames.map(cacheName => {
if (cacheName.startsWith(apex.sw.CORE_CACHE_PREFIX) && cacheName !== apex.sw.CORE_CACHE_NAME) {
return caches.delete(cacheName);
}
})
));
};
apex.sw.cleanAppCaches = (appCacheName) => {
if (appCacheNeedsCleanup) {
appCacheNeedsCleanup = false;
caches.keys().then(cacheNames => Promise.all(
cacheNames.map(cacheName => {
if (cacheName.startsWith(apex.sw.APP_CACHE_PREFIX) && cacheName !== appCacheName) {
return caches.delete(cacheName);
}
})
));
}
};
self.addEventListener("fetch", (event) => {
event.respondWith(
(async () => {
let cacheName;
if (
event.request &&
event.request.url &&
event.request.url.indexOf(apex.sw.CORE_CACHE_MATCHER) >= 0
) {
cacheName = apex.sw.CORE_CACHE_NAME;
} else if (
event.request &&
event.request.url &&
event.request.url.indexOf(apex.sw.APP_CACHE_MATCHER) >= 0
) {
const fileVersion = event.request.url
.split(apex.sw.APP_CACHE_MATCHER)
.pop()
.split("/")[0];
cacheName = apex.sw.APP_CACHE_PREFIX + fileVersion;
apex.sw.cleanAppCaches(cacheName);
}
let cache;
// Try to get from the cache first
if (cacheName) {
cache = await caches.open(cacheName);
const response = await cache.match(event.request);
if (response) {
return response;
}
}
// Then get from network
try {
const response = await fetch(event.request);
// Clone response to put in cache
if (response.ok && cacheName) {
try {
const resClone = response.clone();
cache.put(event.request, resClone);
} catch (error) {
console.warn(error);
}
}
// Return ressource from network
return response;
} catch (error) {
if (event.request.mode === "navigate") {
const offlinePage = "APEX.PWA.OFFLINE";
return new Response(offlinePage, {
headers: { "Content-Type": "text/html" },
});
} else {
return new Response();
}
}
})()
);
});
Web Push Notifications
using firebase