QuotaExceededError: The quota has been exceeded - progressive web app offline mode

Viewed 6532

I am building a progressive web app which I want to function in offline mode also. This means I am caching all the JavaScript, CSS, fonts, etc. with a service worker (workbox) and keep in localStorage whatever I need for the app so that it doesn't crash. For example if the user wants to send a message/upload image when he does not have an active Internet connection, I am storing that in localStorage so that he can just resend it when Internet connection is back online, without having to upload it again.

The current functionality is when the device has no Internet connection I am saving the uploaded file in the localStorage, so that when you are back online you don't have to upload it again, you just hit a "Resend" button to resend the existing uploaded file (image or video) and send it to the server.

Everything works fine when I run it locally on Chrome on mac, the issue appears when I try it on the iPhone, I get this error:

Unhandled Promise Rejection: QuotaExceededError: The quota has been exceeded.

It doesn't work on an Android device either. How can I bypass this error and still keep the functionality to run the app in offline mode?

This is not incognito mode in Safari.

let files = localStorage.files ? JSON.parse(localStorage.files) : [];
files.push(file);
localStorage.files = JSON.stringify(files);
2 Answers

I believe the same quotas do not apply to IndexDb local databases. So it would be worth converting your code to use IndexDb rather than use LocalStorage. It is not easy to find out what limits there are in IOS though - perhaps another contributor would have clearer information on this than me.

localStorage is not where you should cache assets like HTML, JS, CSS, etc. You should use service worker cache instead. You can cache a lot more there. Most browsers use a sliding scale based on available disk space. iOS limits you to 50MB, which is way more than any PWA should really need. For data and media files I use IndexedDB, which helps get around the 50MB Apple limit. I wrote an article on service worker cache limits a while back. https://love2dev.com/blog/what-is-the-service-worker-cache-storage-limit/ I should note I used to use localStorage for my caching before service workers and built some very large web apps and never had an issue with localStorage quotas. Localstorage is not available in the service worker because it is not asynchronous (Promises). If you are trying to cache more than 5MB of JS, CSS and HTML you might want to review your architecture b/c I can guarantee you have a lot of code you are caching that is not being used and will slow your UX way down.

Related