简体   繁体   中英

Add PWA to home screen not working on chrome mobile

I recently got into front end developpement to make an interface for a nodejs server hosted on a raspberry pi. I heard of progressive web app and wanted the user to be able to install it on his phone. So here are the manifest and the service worker script. Manifest:

{
  "name": "Philips D6330",
  "short_name": "Philips D6330",
  "description": "A control app for the Philips D6330",
  "icons": [
    {
      "src": "https://192.168.1.26/cdn/favicon.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start_url": "https://192.168.1.26",
  "display": "fullscreen",
  "orientation": "portrait",
  "theme_color": "#333333",
  "background_color": "#333333",
  "scope": "/"
}

Service Worker:

const CACHE_NAME = 'cache';
const CACHE = [
  '/',
  '/cdn/offline.html',
  '/cdn/style.css',
  '/cdn/favicon.png',
  '/cdn/linetoB.ttf',
  '/cdn/linetoL.ttf',
  '/cdn/neon.ttf',
  '/cdn/not.png',
  '/cdn/next.png',
  '/cdn/pause.png',
  '/cdn/play.png',
  '/cdn/previous.png',
  '/cdn/dots.png',
  '/cdn/rfid.png'
];

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        return cache.addAll(CACHE)
      })
      .then(self.skipWaiting())
  )
})

self.addEventListener('fetch', function(event) {
  if (event.request.mode === 'navigate') {
    event.respondWith(
      fetch(event.request)
      .catch(() => {
          return caches.open(CACHE_NAME)
          .then((cache) => {
              return cache.match('/cdn/offline.html');
          })
      })
    );
  }
  else {
    event.respondWith(
      fetch(event.request)
      .catch(() => {
        return caches.open(CACHE_NAME)
        .then((cache) => {
            return cache.match(event.request)
        })
      })
    );
  }
})

self.addEventListener('activate', function(event) {
  event.waitUntil(
    caches.keys()
      .then((keyList) => {
        return Promise.all(keyList.map((key) => {
          if (key !== CACHE_NAME) {
            console.log('[ServiceWorker] Removing old cache', key)
            return caches.delete(key)
          }
        }))
      })
      .then(() => self.clients.claim())
  )
})

I think also relevant to tell you that all of this happens on my local network so my node server uses https with a self-signed certificate made using this tutorial: https://medium.com/@tbusser/creating-a-browser-trusted-self-signed-ssl-certificate-2709ce43fd15 But even tho it's a self-signed certificate, the service worker seem to registers well on firefox and chrome, as it stores the files and displays the offline page when offline.

Here is my problem: when I want to install it from the desktop version of chrome I can but not chrome mobile (or samsung internet)... here is the piece of code i use to make it instalable:

<script  defer>
    window.addEventListener('beforeinstallprompt', (event) => {
      console.log('👍', 'beforeinstallprompt', event);
      // Stash the event so it can be triggered later.
      window.deferredPrompt = event;
    });

    butInstall.addEventListener('click', () => {
      console.log('👍', 'butInstall-clicked');
      const promptEvent = window.deferredPrompt;
      if (!promptEvent) {
        // The deferred prompt isn't available.
        return;
      }
      // Show the install prompt.
      promptEvent.prompt();
      // Log the result
      promptEvent.userChoice.then((result) => {
        console.log('👍', 'userChoice', result);
        // Reset the deferred prompt variable, since
        // prompt() can only be called once.
        window.deferredPrompt = null;
      });
    });

    window.addEventListener('appinstalled', (event) => {
      console.log('👍', 'appinstalled', event);
    });

  </script>

It comes from here https://web.dev/codelab-make-installable/

Here is a screenshot of the before install prompt event with the lighthouse report if it can help (by the way the plus sign in the url shows it's working): console log infos

But on mobile the plus sign doesn't show up and nothing happens when I click the button... And as I don't have acces to the console I can't see any errors...

------ Edit ------

After using alert to log what the console says, I think the problem comes from the service worker does register well because I get this: "ServiceWorker registration failed: SecurityError: Failed to register a ServiceWorker for scope (' https://192.168.1.26/ ') with script (' https://192.168.1.26/sw.js '): An SSL certificate error occurred when fetching the script.".

Is there a way to make the browser trust my self-singed certificate?

Any help, suggestion or comment is welcome ^^

Its a .webmanifest and you dont match the criteria. You need an 512x512 AND an 192x192 icon.

As start_url i would just use /?source=pwa

  "icons": [
    {
      "src": "icon.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "big_icon.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "start_url": "/?source=pwa",

After that you need to link your webmanifest with <link>

<link rel="manifest" href="/manifest.webmanifest">

Check if the paths are all correct.

Here is my own little "library" to abstract things: https://github.com/ilijanovic/serviceHelper (its under development tho)

If you met all criteria, then you can make your app installable

Here its how it works with my library. You instantiate the class and pass the path to the service worker.

var sh = new ServiceHelper("./sw.js");

sh.init().then(response => {
   console.log("Initialized");
})

sh.on("notinstalled", (e) => {

   console.log("App is not installed");

   //do some stuff. For example enable some button
   //button.classList.remove("disabled");

})
butInstall.addEventListener('click', () => {
   sh.installApp().then(e => {
      // e = user choice event
      console.log(e);
   }).catch(err => {
      // error if the app is already installed
      console.log(err);
   })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM