I am trying to implement PWA in standalone mode on Android and iOS.
I have a secure node.js server (HTTPS) and everything is apparently working fine (index.html, manifest.json, serviceWorker.js, ...).
The application runs correctly from Chrome and can be added to the home screen and run in standalone mode on the PC. It also works in standalone mode on iOS (Safari), but not on Android (Chrome).
Because of this, I tested three different PWAs: with a basic example of ionicPWA, another example of angularPWA, and then with an own PWA. The behavior is the same, if I deploy applications on a server like Firebase, then the apps work in standalone mode on both iOS and Android. But if I deploy the apps on my node.js server, the application only works in standalone mode on iOS but not on Android.
I have tested on different Android devices with the v67.0.3396.87 of Chrome, on Android 8.1.0, 7.0.0 and 6.0.0. The PWA only opens in browser mode.
I have seen other questions and answers about this behavior (ref1, ref2, ref3) but I have not found the solution.
Could this be a bug of Chrome-v67? Or can it be some configuration of my server that affects the behavior of Chrome on Android?
Any ideas?
UPDATE1: index.html, manifest.json, seviceWorker (sw.js) and audit with Chrome devTools
index.html (head)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--title-->
<title>PWA Test</title>
<!--icon-->
<link rel="shortcut icon" type="image/png" href="img/favicon.png"></link>
<!--color-->
<meta name="theme-color" content="#FB314E">
<!--for mobile-->
<meta name="MobileOptimized" content="width">
<meta name="HandheldFriendly" content="true">
<!--for Apple devices-->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="apple-touch-icon" href="img/favicon.png"></link>
<link rel="apple-touch-startup-image" href="img/favicon.png"></link>
<!-- pwa configuration-->
<link rel="manifest" href="manifest.json"></link>
<!--style-->
<link rel="stylesheet" href="css/styles.css"></link>
<!--jQuery-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--Scripts-->
<script src="main.js"></script>
</head>
manifest.json
{
"name": "PWA 3002 Test",
"short_name": "PWA 3002",
"description": "PWA aplication",
"background_color": "#FFF",
"theme_color": "#FB314E",
"orientation": "portrait",
"display": "standalone",
"start_url": "./index.html?utm_source=web_app_manifest",
"scope": "./",
"lang": "es-ES",
"icons": [
{
"src": "./img/favicon-1024.png",
"sizes": "1024x1024",
"type": "image/png"
},
{
"src": "./img/favicon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "./img/favicon-384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "./img/favicon-256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "./img/favicon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "./img/favicon-128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "./img/favicon-96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "./img/favicon-32.png",
"sizes": "32x32",
"type": "image/png"
},
{
"src": "./img/favicon-16.png",
"sizes": "16x16",
"type": "image/png"
}
]
}
sw.js (service worker)
// name and version of cache
const CACHE_NAME = 'v1_cache_pwa';
// for cache
var urlsToCache = [
'./',
'./css/styles.css',
'./img/favicon.png',
'./img/1.png',
'./img/2.png',
'./img/3.png',
'./img/4.png',
'./img/5.png',
'./img/6.png',
'./img/favicon-1024.png',
'./img/favicon-512.png',
'./img/favicon-384.png',
'./img/favicon-256.png',
'./img/favicon-192.png',
'./img/favicon-128.png',
'./img/favicon-96.png',
'./img/favicon-64.png',
'./img/favicon-32.png',
'./img/favicon-16.png'
];
// install event
self.addEventListener('install', e => {
e.waitUntil(
caches.open(CACHE_NAME)
.then(cache => {
return cache.addAll(urlsToCache)
.then(() =>{
self.skipWaiting();
});
})
.catch(err => {
console.log('No se ha registrado el cache', err);
})
);
});
// activate event
self.addEventListener('activate', e => {
const cacheWhiteList = [CACHE_NAME];
e.waitUntil(
caches.keys()
.then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if(cacheWhiteList.indexOf(cacheName) === -1){
// Borrar elementos que no se necesitan
return caches.delete(cacheName);
}
})
);
})
.then(() => {
//Activar cache
self.clients.claim();
})
);
});
// fetch event
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request).then(function(response) {
return response || fetch(event.request);
})
);
});
Chrome DevTools audit (on PC)
Testing three apps (ionicPWA example, angularPWA example, my own PWA):
with ionicPWA two warngins appears in the console:
*vendor.js:1: Native: tried calling StatusBar.styleDefault, but Cordova is not available. Make sure to include cordova.js or run in a device/simulator
E
*DevTools failed to parse SourceMap: https://xxx.xxx.xxx/build/sw-toolbox.js.map
(index):28 service worker installed
with AngularPWA no messages/errors/warnings appears...
with my own PWA app, the same behavior.. no messages/errors/warnings appears in the console of Chrome devTools on PC
See Question&Answers more detail:
os