2

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

jo_va
  • 13,504
  • 3
  • 23
  • 47
actanony
  • 117
  • 1
  • 11
  • When deployed to the server(s) that are not working, have you tested there with the chrome dev audit tools? Do you see "user can be prompted to install the Web App" with no other errors? – Mathias Aug 03 '18 at 21:29
  • Thank you @mathias. I added more details in the post (content of some files and the audit with Chrome devTools). And yes!, when I open the first time any of the three test applications on the mobile, the option to add the application to the home screen appears and it's added correctly. – actanony Aug 05 '18 at 23:12
  • You may want to try in Chrome Beta 68 - If it works there, then it most likely would be a 67 bug (I think). Also, you may want to consider uploading your app to a free site (like Glitch.me) for a few minutes to see if it is your environment. Just remember to type in HTTPS for your URL if you use that. They do not redirect to https if you do not. – Mathias Aug 05 '18 at 23:40
  • Thanks @mathias, I tried Chrome Beta 68 and it does not work. But, I do not understand what is happening ... There must be some configuration or something that makes the Android standalone mode not work when the application is deployed on my node.js server, because the application works when I deploy the applications in Firebase: https://np-2805.firebaseapp.com/ (example of ionicPWA) – actanony Aug 06 '18 at 00:24
  • Unfortunately your probably debugging an issue that Google should fix. – Mathias Aug 06 '18 at 00:26
  • Finally I have solved the problem. When I have configured the node.js server listening on the default port 443, the PWA application works in standalone mode on Android. Thanks @mathias for your support. – actanony Aug 06 '18 at 11:21

1 Answers1

4

I have solved the problem. A colleague told me that maybe the problem was due to the port configured on the server. I had configured the server node.js listening on a specific port (https://mydomain:xxxx), not in the default port (443), and this for some reason caused the PWA application not work in standalone mode on Android. I set up the server in the default port "443" and the PWA application already works correctly in standalone mode in both Android and iOS. Thanks to all.

actanony
  • 117
  • 1
  • 11