-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Description
Use case
Flutter has a very strong caching done by it's service worker, which sometimes forces a user to have to clear the cache for the app even when resources are sent from the web server with a no-cache and already expired date headers. This sometimes causes problems because even with the proper code already in place in the server, the app takes a while to retrieve the latest resources from it. Sometimes, even adding ?v=(timestamp) to force this reload don't work as the cache is not controlled by the browser, but by this flutter service worker.
Proposal
Based on the version/build number of the app, cache could be deleted to force the retrieval of the latest versions from the server. This could easily and elegantly be achieve by using package info which is still not implemented as stated on #46609.
Current Successful Workaround
Currently in our pipelines we are dumping a file named version.txt in the root of the published code that contains the values from pubspec.yaml with build number updated and call caches to delete the caches everytime this build number is changed. Code is not beautiful but definitely may help those who are facing this problem:
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
//getting rid of undesired cache before running the app
var seconds = new Date().getTime()
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", '/version.txt?v=' + seconds, true);
xmlhttp.onload = function () {
if (xmlhttp.status == 200) {
var buildNumber = xmlhttp.responseText.split('+')[1];
var currentBuildNumber = window.localStorage.getItem('buildNumber');
if (currentBuildNumber && currentBuildNumber != buildNumber) {
caches.delete('flutter-app-manifest');
caches.delete('flutter-temp-cache');
caches.delete('flutter-app-cache');
}
window.localStorage.setItem('buildNumber', buildNumber);
}
navigator.serviceWorker.register('flutter_service_worker.js');
}
xmlhttp.error = function () {navigator.serviceWorker.register('flutter_service_worker.js');}
xmlhttp.abort = function () {navigator.serviceWorker.register('flutter_service_worker.js');}
xmlhttp.timeout = function () {navigator.serviceWorker.register('flutter_service_worker.js');}
xmlhttp.send();
});
}
</script>