Firebase Hosting Flutter Web App not clearing Cache of first deploy

3,377

Solution 1

Try this:

In your flutter app, in the index.html within the web folder, add a version number after the src="main.dart.js

So your new line will look like this:

<script src="main.dart.js?version=1" type="application/javascript"></script>

Then increment the version number to 2, etc before you do each build.

update june 2021: add this line in index.html as the last script in the body

Solution 2

I see Flutter now include this script by default in index.html if project is created recently which has serviceWorkerVersion element which updates the version when compiling:

<script>
var serviceWorkerVersion = null;
var scriptLoaded = false;
function loadMainDartJs() {
  if (scriptLoaded) {
    return;
  }
  scriptLoaded = true;
  var scriptTag = document.createElement('script');
  scriptTag.src = 'main.dart.js';
  scriptTag.type = 'application/javascript';
  document.body.append(scriptTag);
}

if ('serviceWorker' in navigator) {
  // Service workers are supported. Use them.
  window.addEventListener('load', function () {
    // Wait for registration to finish before dropping the <script> tag.
    // Otherwise, the browser will load the script multiple times,
    // potentially different versions.
    var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
    navigator.serviceWorker.register(serviceWorkerUrl)
      .then((reg) => {
        function waitForActivation(serviceWorker) {
          serviceWorker.addEventListener('statechange', () => {
            if (serviceWorker.state == 'activated') {
              console.log('Installed new service worker.');
              loadMainDartJs();
            }
          });
        }
        if (!reg.active && (reg.installing || reg.waiting)) {
          // No active web worker and we have installed or are installing
          // one for the first time. Simply wait for it to activate.
          waitForActivation(reg.installing ?? reg.waiting);
        } else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
          // When the app updates the serviceWorkerVersion changes, so we
          // need to ask the service worker to update.
          console.log('New service worker available.');
          reg.update();
          waitForActivation(reg.installing);
        } else {
          // Existing service worker is still good.
          console.log('Loading app from service worker.');
          loadMainDartJs();
        }
      });

    // If service worker doesn't succeed in a reasonable amount of time,
    // fallback to plaint <script> tag.
    setTimeout(() => {
      if (!scriptLoaded) {
        console.warn(
          'Failed to load app from service worker. Falling back to plain <script> tag.',
        );
        loadMainDartJs();
      }
    }, 4000);
  });
} else {
  // Service workers not supported. Just drop the <script> tag.
  loadMainDartJs();
}
Share:
3,377
Admin
Author by

Admin

Updated on December 19, 2022

Comments

  • Admin
    Admin over 1 year

    We build a flutter web app and deployed it via firebase hosting. Unfortunately, we didnt configure any caching settings in our initial deploy.

    Now we deployed a newer version of our website but people still get the old website shown form the first deploy. What we tried so far:

    Adding version no. to our index.html:

    <"script src="main.dart.js?version=1" type="application/javascript"></script>
    

    Adding meta Data in our header in index.html:

      <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
      <meta http-equiv="Pragma" content="no-cache" />
      <meta http-equiv="Expires" content="0" />
    

    In our firebase.json we added the following headers:

    "headers": [
          {
            "source": "**",
            "headers": [
              {
                "key": "Cache-Control",
                "value": "max-age=10"
              }
            ]
          }
        ]
    

    All of these attemps were without any luck. We think that the problem is that the newer version doesnt have those entries in the files. How can we force this to update to our newest version? We even consider opening a new firebase project if that might help.

    Thanks a lot for any help!

  • Vincenzo
    Vincenzo almost 4 years
    thank you, I actually didn't see in docs and just assumed that the new deployed was replacing the one before the messages from terminal are finalizing version..., version finalized, releasing new version..., release complete.. just now I realize "version.." hahah. Many thanks
  • August Kimo
    August Kimo almost 3 years
    This didn't work for me. It still requires a refresh or two before updating (no difference).
  • ali
    ali over 2 years
    if i already do flutter build web normally before this, and want to implement this -pwa-strategy=none, do i have to clear the cache first for it to work? or it will work immediately
  • iqfareez
    iqfareez over 2 years
    @ali You may run flutter clean first.
  • ali
    ali over 2 years
    other than that do i need to change build number everytime i want to deploy new version?
  • iqfareez
    iqfareez over 2 years
    not necessarily