No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    [Solved] PWA force refresh when new version released?

    Framework
    22
    60
    51767
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • C
      ChrisO last edited by

      Further update now that that iOS 13 has been released.

      I removed skipWaiting() and clientClaim() from our configuration settings. I can open our PWA and it will show the old version. After closing the app via the app switcher, when the app restarts, it has updated to the new version. iOS might close a suspended PWA after a certain amount of time has passed without any user action, although as with most things PWA related on iOS, information from Apple is scarce.

      1 Reply Last reply Reply Quote 1
      • P
        PiotrG last edited by

        Sorry to resurrect this old thread but I am having the same problems as some users above. I have a PWA with a custom service worker. In App.vue in a preFetch method, I read a file called version.json and compare that with a localstorage “version” property. If the localstorage is lower, I then create a Quasar Dialog that there is a newer version available and then do window.location.reload(true) when the user clicks “ok”. That all works, however it doesn’t fetch the latest app data. Only when I either close the app and reopen it or in a browser I do a ctrl-f5 to refresh.

        When changing to generatesw instead of injectmanifest, thus eliminating my custom service worker (which I want because of various route caching strategies), quasar creates a red bar that a new version is available and when clicking that, it fetches the latest version of the app from the server.

        Does anyone know how generateSW is doing this and how I could duplicate that functionality in my custom service worker?

        dobbel ssuess 2 Replies Last reply Reply Quote 0
        • dobbel
          dobbel @PiotrG last edited by

          @PiotrG

          Thread with similar problem:
          https://forum.quasar-framework.org/topic/6959/chrome-but-not-ff-nor-safari-randomly-fails-pwa-update/29?_=1604419034026

          btw I would start new thread for this.

          1 Reply Last reply Reply Quote 0
          • ssuess
            ssuess @PiotrG last edited by ssuess

            @PiotrG I am pretty sure you are running into the same problem I was running into originally, which is that a simple reload will not work because you can’t let go of the app itself while you are using it without invoking the update method of your registration in navigator.serviceWorker see above for that code, and also remember that you must have skipWaiting and clientsClaim present in your service worker (they can be loaded into the service worker when using GenerateSW if you add workboxOptions: { skipWaiting: true, clientsClaim: true } in your quasar.conf.js file btw)

            1 Reply Last reply Reply Quote 1
            • T
              turigeza last edited by

              @ssuess Which one are you using right now ? The last one posted here …
              https://forum.quasar-framework.org/topic/2560/solved-pwa-force-refresh-when-new-version-released/31?_=1605731186657

              forceSWupdate () {
                if ('serviceWorker' in navigator) {
                  navigator.serviceWorker.getRegistrations().then(function (registrations) {
                    for (let registration of registrations) {
                      registration.update()
                    }
                  })
                }
              }
              
              1 Reply Last reply Reply Quote 0
              • ssuess
                ssuess last edited by

                @turigeza I use the function above when I want to trigger an update from within my code, and within my service worker I have code that checks my local version number, clears localstorage, and then forces a reload. I also have to unfortunately check in SW for what browser we are using, because different browsers behave differently when reloaded. You can see that code and explanation in this thread: https://forum.quasar-framework.org/topic/6959/solved-chrome-but-not-ff-nor-safari-randomly-fails-pwa-update/41?_=1605780104096

                metalsadman 1 Reply Last reply Reply Quote 1
                • metalsadman
                  metalsadman @ssuess last edited by

                  @ssuess said in [[Solved] PWA force refresh when new version released?](/post

                  @turigeza I use the function above when I want to trigger an update from within my code, and within my service worker I have code that checks my local version number, clears localstorage, and then forces a reload.

                  Mind sharing the snippet

                  1 Reply Last reply Reply Quote 1
                  • ssuess
                    ssuess last edited by ssuess

                    I linked to it above, but here it is again in more or less final form (with domains changed):

                    import localforage from 'localforage'
                    
                    register(process.env.SERVICE_WORKER_FILE, {
                      ready () {
                        console.log('App is being served from cache by a service worker.')
                      },
                      registered (registration) { // registration -> a ServiceWorkerRegistration instance
                        console.log('Service worker has been registered.')
                        // console.log('scope: ' + registration.scope)
                      },
                      cached (registration) { // registration -> a ServiceWorkerRegistration instance
                        console.log('Content has been cached for offline use.')
                      },
                      updatefound (registration) {
                        console.log('New content is available; please refresh.')
                        /* eslint-disable no-extra-boolean-cast */
                        if (!!window.chrome) { // for chromium based browsers
                          fetch('https://pwatest.mydomain.com/av.json?t=' + Date.now())
                            .then(response => {
                              response.json().then(function (data) {
                                const r = confirm('There is a new version (' + data.version + ') available. Your version will be updated, alright? ' + data.message)
                                if (r === true) {
                                  if (data.clearStorage === true) {
                                    localforage.clear().then(function () {
                                      // Run this code once the database has been entirely deleted.
                                      console.log('Database is now empty. so there now.')
                                      location.reload(true)
                                    }).catch(function (err) {
                                      // This code runs if there were any errors
                                      console.log(err)
                                    })
                                  }
                                } else {
                                  console.log('You pressed Cancel!')
                                }
                              })
                              console.log('response:', response)
                            })
                            .catch(error => {
                              console.error(error)
                            })
                          }
                        },
                        updated (registration) { // registration -> a ServiceWorkerRegistration instance
                          console.log('New content is available; please refresh.')
                          if (!window.chrome) { // for non chromium browsers
                          fetch('https://pwatest.mydomain.com/av.json?t=' + Date.now())
                            .then(response => {
                              response.json().then(function (data) {
                                const r = confirm('There is a new version (' + data.version + ') available. Your version will be updated, alright? ' + data.message)
                                if (r === true) {
                                  if (data.clearStorage === true) {
                                    localforage.clear().then(function () {
                                      // Run this code once the database has been entirely deleted.
                                      console.log('Database is now empty. so there now.')
                                      location.reload(true)
                                    }).catch(function (err) {
                                      // This code runs if there were any errors
                                      console.log(err)
                                    })
                                  }
                                } else {
                                  console.log('You pressed Cancel!')
                                }
                              })
                              console.log('response:', response)
                            })
                            .catch(error => {
                              console.error(error)
                            })
                          }
                        },
                        offline () {
                          console.log('No internet connection found. App is running in offline mode.')
                        },
                        error (err) {
                          console.error('Error during service worker registration:', err)
                        }
                    })
                    
                    1 Reply Last reply Reply Quote 2
                    • T
                      turigeza last edited by

                      @ssuess Thank you for sharing the code and explaining it as well.

                      1 Reply Last reply Reply Quote 1
                      • D
                        danbars last edited by

                        It seems that Quasar now supports this out of the box: https://quasar.dev/quasar-cli/developing-pwa/configuring-pwa#Reload-%26-Update-Automatically

                        ssuess 1 Reply Last reply Reply Quote 1
                        • ssuess
                          ssuess @danbars last edited by

                          @danbars Quasar supports loading clientsClaim and skipWaiting directives into the SW file, but for a number of reasons this is not enough. Also, while on supported platforms it will update your PWA, it will do so silently. I needed a way to do all of the following:

                          • Control or initiate the update process
                          • Set my own versioning
                          • Notify users about updates
                          • Perform actions related to the update
                          • Work around platform and browser limitations and inconsistencies so that it works the same everywhere and without failure
                          1 Reply Last reply Reply Quote 0
                          • M
                            Marin Vartan @Carlitos last edited by

                            @carlitos thank you man, you save a lot of time

                            1 Reply Last reply Reply Quote 0
                            • Z
                              zeppelinexpress last edited by

                              Hi guys, I have a doubt, how does the browser know there is a new update? is the package-lock.json?
                              just changing this:
                              {
                              “name”: “app”,
                              “version”: “0.0.1”,

                              is enough to automatically update on android/desktop browsers/installed versions?

                              ssuess 1 Reply Last reply Reply Quote 0
                              • ssuess
                                ssuess @zeppelinexpress last edited by

                                @zeppelinexpress when you build your project (for a PWA) there will be new cache signatures, which a PWA should read and then force an update. However, as mentioned above this is inconsistent across platforms and I have found it necessary to make my app check a version string that I set on the server and call the update mechanisms at that point which works everywhere. See the code examples above for what I use to make this work.

                                1 Reply Last reply Reply Quote 1
                                • C
                                  ChrisO last edited by ChrisO

                                  Rejoining this thread, because I’ve figured out a complete solution for a user controlled app refresh (similar to the pop-up in the Quasar documentation) that might be useful for others who have the same issue. It’s a combination of ideas taken from the Workbox Advanced Recipes (https://developers.google.com/web/tools/workbox/guides/advanced-recipes#offer_a_page_reload_for_users) and an article by Doug Allrich. It uses the Workbox-Window plug-in from Google.

                                  <template>
                                    <q-dialog v-model="displayUpdatePrompt">
                                      <q-banner>
                                        A new version is available.
                                       <template v-slot:action>
                                         <q-btn label="Update" @click="refreshApp" />
                                       </template>
                                     </q-banner>
                                    <q-dialog>
                                  </template>
                                  
                                  <script>
                                  import { Wokbox } from 'workbox-window'
                                  
                                  export default {
                                  data() {
                                    return {
                                    displayUpdatePrompt: false,
                                    workbox: null,
                                    }
                                  },
                                  methods: {
                                    refreshApp() {
                                      this.workbox.addEventListener('controlling', () => {
                                        window.location.reload()
                                      })
                                     this.workbox.messageSkipWaiting()
                                    }
                                  },
                                  created() {
                                    if ('service-worker' in navigator) {
                                      this.workbox = new Workbox('/service-worker.js')
                                  
                                     this.workbox.addEventListener('waiting', (event) => {
                                      this.displayUpdatePrompt = true
                                      })
                                      this.workbox.register()
                                    }
                                  }
                                  }
                                  </script>
                                  
                                  1 Reply Last reply Reply Quote 1
                                  • tlloyduk
                                    tlloyduk last edited by

                                    @Chris-0 awesome! would you add this as a component and then call it from App.vue or is there a best practice for where to position this in a Quasar project ?

                                    1 Reply Last reply Reply Quote 0
                                    • I
                                      imaryjones09876 last edited by

                                      Troubleshooting methods to solve Pogo games not working issue
                                      Clear the cache
                                      If Pogo games are not working on your system, then the first thing that you need to do solve this problem is to clean the cache. Read out the instructions below for clearing the cache.

                                      1. First, go to your browser’s settings and open your browser’s history
                                      2. Now, select browser history
                                      3. As you select browser’s history, a number of check boxes will open up in front of you together with the check boxes, out of those check boxes, one is cache.
                                      4. Now, you need to select cache and remove the cache by clicking on the button of delete.
                                        After deleting the cache from the browser, close the browser. Now, launch the browser again and open the Pogo website on it. Now, check whether your loading problem is resolved or not. If you are still not able to load the page, then you need to clear Java cache. In case your game is backed by flash, then erase the flash cache.
                                        Restart or refresh our system
                                        If you are unable to load Pogo games webpage on your computer, then try refreshing the page by pressing F5. You can also reload the page by clicking on the reload icon placed on the top of your browser. If you do so, then your internet browser will avoid the cache and you will be able to access the Pogo.com page.
                                        Use some other browser
                                        If you are not able to fix Pogo games not working issue by any of the above-stated methods, then use another browser to play virtual games. This will definitely solve your problem. Sometimes the problem fixes by switching the browser.
                                        Generally people use web browsers like Internet Explorer, Google Chrome, and Firefox etc. But there are several other internet browsers that people use, which are not fit for online gaming. So, use compatible browsers for virtual gaming.
                                        Get More Help https://pogo-supportcenter.com/pogo-games-not-loading/
                                        pogo sign in problems, pogo support number, pogo account, club pogo sign in page, pogo games sign in page, pogo stuck online, pogo customer service phone number, pogo customer support number, pogo support phone number, pogo games not loading, pogo login problems, Pogo customer Service, Pogo Billing Support, Pogo Billing Support Number, Pogo Customer Service Number, Pogo Gems Not Showing, Pogo login issues, Pogo games not working, pogo games won ‘t load, pogo troubleshooter, pogo games down
                                      1 Reply Last reply Reply Quote 0
                                      • S
                                        SharpBCD last edited by

                                        I have read all documentation and this thread but I still encounter a problem. My service worker is not triggered when I update the server as it should, it is only triggered when I open a new tab and access the app again. Any suggestion? Can I force to check for updates every 5 seconds, let’s say?

                                        1 Reply Last reply Reply Quote 0
                                        • S
                                          SharpBCD last edited by

                                          Solved with this pcs of code:

                                          		console.log('%c Service worker is active.', 'color: magenta', registration);
                                          		const updateManual = () => {
                                          			registration.update().catch((er)=>console.error('Error on update worker', er));
                                          		};
                                          		setInterval(updateManual, 500); // 500ms works for me, but you may want to set it higher.
                                          	},```
                                          in case someone else need it.
                                          1 Reply Last reply Reply Quote 0
                                          • First post
                                            Last post