2

Can a webapp have reliable local data storage on Android?

If not then can a web application be installed as a local application, to gain access to privileged APIs? Perhaps (this is just a wild guess) as a "Chrome extension" or an "Installed web app"?


Details

A single-page web application is a static web page on a web server without a backend-end database or API (i.e. there is no fetch within the application).

The application stores and uses data on the user's device, and I want that storage to be reliable, i.e.

  • I do not mind having to ask the user for permission
  • But the data must not then be deleted without the user's consent

Now I'm worried that this article -- Managing HTML5 Offline Storage (from 2015) -- says,

Persistent storage is storage that stays in the browser unless the user expunges it. It is available only to apps that use the File System API, but will eventually be available to other offline APIs like IndexedDB and Application Cache.

... and the section Running out of storage suggests that storage may be deleted:

  • If the user has more than 5 "offline" applications
  • If the device begins to run out of disk space

The relevant APIs seems to be these:

Browsers API
All Window API: localStorage
Web Storage - name/value pairs
All IndexedDB
not Android! Filesystem & FileWriter (a sandboxed file system)
not Android! File System Access (not in a sandbox)

So can it be done on Android, or is there any workaround?

And the APIs mentioned in the article -- e.g. webkitPersistentStorage -- are apparently deprecated. Have these been replaced by something, and are they available on Android?

ChrisW
  • 54,973
  • 13
  • 116
  • 224
  • I don't think so (but: I might be wrong!). But you can use, for example, [Cordova](https://cordova.apache.org/) to convert a single-page webapp to an installable Android APK quite easily. It uses the Chrome WebView under the hood, so the installed size remains relatively small. – Thomas Feb 20 '22 at 13:08
  • ... although [Cordova's popularity is waning](https://medium.com/codex/the-sunset-of-apache-cordova-alternatives-for-cross-platform-mobile-development-in-2022-9da34234c992). I personally have good experiences with Flutter, but if you have already built the app... \*shrug\* – Thomas Feb 20 '22 at 13:12
  • Oh right, there's also [Capacitor](https://capacitorjs.com/). I should stop talking. The last time I looked into this stuff was about a year ago, which is like 75 in JavaScript-years ;) – Thomas Feb 20 '22 at 13:18
  • @Thomas ... or repost it as an answer -- it seems to be on-topic -- to avoid some well-meaning moderator's deleting it. – ChrisW Feb 20 '22 at 13:21
  • I don't feel qualified to answer a definite "no, this is impossible". And recommendations for frameworks are definitely off-topic, hence comments. – Thomas Feb 20 '22 at 13:22
  • @Thomas I posted an answer which says maybe there is a solution. But still thank for the comments about converting a webapp to an Android APK, I'd vaguely heard that might be possible but I didn't know how to Google for it. – ChrisW Feb 20 '22 at 16:23

1 Answers1

1

According to this article -- Persistent storage (May 2020) -- there's a storage.persist() method:

// Request persistent storage for site
if (navigator.storage && navigator.storage.persist) {
  const isPersisted = await navigator.storage.persist();
  console.log(`Persisted storage granted: ${isPersisted}`);
}

If the persistent storage permission is granted, the browser will not evict data stored in:

  • Cache API
  • Cookies
  • DOM Storage (Local Storage)
  • File System API (browser-provided and sandboxed file system)
  • IndexedDB
  • Service workers
  • App Cache (deprecated, should not be used)
  • WebSQL (deprecated, should not be used)

MDN currently warns that this is "experimental technology" -- but most browsers seems to have implemented it including Chrome on Android.

ChrisW
  • 54,973
  • 13
  • 116
  • 224
  • A warning: This [can't be un-done](https://stackoverflow.com/questions/50148083/how-to-undo-navigator-storage-persist)! As the article states: _"At this time, there is no programmatic way to tell the browser you no longer need persistent storage."_ I.e. there is no method like `.unpersist()` or something. See also https://stackoverflow.com/questions/50148083/how-to-undo-navigator-storage-persist. – kca Feb 13 '23 at 21:13
  • You can delete persisted data though, programmatically or via the browser's UI. – ChrisW Feb 14 '23 at 03:16
  • _Via UI:_ you mean delete all data of all domains, right ? But one might want to keep data from other domains. -- _Programmatically:_ You mean deleting specific stored data, right ? But in a new project you might not want to have to delete all data you ever have stored in different projects. -- If I'm wrong, can you please add to your answer how that can be done ? I'd love to know. – kca Feb 14 '23 at 09:42
  • I use the persist API in the settings of the app at https://cwellsx.github.io/time/ which writes to the browser's database via the https://www.npmjs.com/package/idb package. The app can use the idb API to edit the database. The user can edit the database in Chrome Developer tools or via the UI like chrome://settings/content/all – ChrisW Feb 14 '23 at 09:51