My team of engineers created an Android app that integrates with ODK Collect, using intents to instantiate a Form, as well as Xform intents to retrieve data from our app. This approach has worked well for us for over 18 months.
We are in the process of re-writing our app (new business requirements), and are considering building a PWA. Our business folks would like a more "device agnostic" version of our app, where users could see our data outcomes on various platforms and devices (e.g. Android tablet, Android phone, web browser). Since we need to be able to render and submit existing ODK forms, we are considering this approach:
PWA user clicks on a button to launch an ODK form within a browser.
PWA creates a one-time use Public Access Link (PAL), and renders the form via the link within the PWA.
Once the PAL's form is submitted, revoke access to the PAL (hopefully limiting nefarious or duplicate submissions).
Some thoughts:
This works online. How do we / can we do this offline? Enketo references offline capabilities, but how?? We would like to consider ODK Web Forms (the wave of the future ), but offline capabilities are way down on the roadmap.
If we incorporated ODK Central APIs, how could we mitigate offline experiences?
What other approaches to multi-platform, offline-capable would others recommend?
You could build a PWA that integrates either Enketo or WebForms (submission saving with WebForms is in the works, so if you wait a bit you'll have example code). If you use a serviceworker you can take care of making the app (= your web app bundle) offline in a straightforward manner.
But what to do with the submission data when offline is another matter; you'll have to save it to a browser-local DB (eg IndexedDB) and build some sync mechanism. I think that'll be the most challenging part, especially if your client apps are offline for long stretches of time (so you'll have network partitions around the clock, in distributed system terms) and can generate clashing data (eg Entity update conflicts) based on their respective diverging world views.
You could use a transparent ServiceWorker setup to this end - for the form/assets retrieval path, and even for the form submission (POST) path. But a more deliberate sync mechanism would probably be better; making it easier to deliberately precache forms and handle submissions.
I'd recommend the PWA route for ease of distribution. But it's worth appreciating that it's not as simple as "I know web sites so I know PWAs" - just like anything it requires a bit of domain expertise especially when it comes to handling app upgrades in combination with API versions, data format versions and a host of implicit mini-protocols and mini-formats that suddenly start to matter when a webapp is made offline-capable and generates data based on a detached world view . With a PWA it's easy to step into distributed systems land with distributed systems problems unwittingly The problems faced are the same as for an offline Android app, but the progressive nature of development of an offline PWA makes it all too easy to ignore certain realities.
Enketo does have an offline mode which is requested through the URL structure. If you're using Public Access Links, you can replace the /single/ part of the URL with /x/. For regular authenticated form links, add /x/ after the /- part of the URL. This lets you access the Enketo Express PWA which saves form assets for offline use and can have an offline queue of completed submissions. These can be manually sent or are automatically attempted to be sent when a connection becomes available and Enketo is in the foreground.
We don't expose this mode explicitly through Central because we have found that it's a confusing user experience and that end users tend to forget to submit after having worked offline. With some minimal training, though, people have had great success with it.
This could be something you launch from your own custom PWA. If you want a more embedded experience, you would likely be looking at wrapping Enketo Core within your app, possibly taking inspiration from Enketo Express' PWA approach.
As @Nonsequitur describes, for anything that makes requests to the ODK Central API, you'd have to develop your own service worker layer which can make requests when online, store the response data, and serve it locally when offline.
Central is designed to detect and surface these kinds of conflicts so it's not something that a client would need to worry about.
Yes! You're right, I didn't mean to imply that. Central is great at handling the conflicts.
I merely wanted to convey that there'll be more opportunity for conflicts the more clients you have and the longer they are offline. Also depending, of course, on the nature of the survey and how intertwined the data is that those clients are submitting based on their respective world views, which diverge over time while offline.
We will be doing exactly the same in the coming months: a web app integrating web forms and syncing offline state when connectivity is restored.
Lets exchange info / notes about how things go!
There are loads of great libraries taking a local first approach to web development. I would advocate adopting one of them to avoid having to re-engineer a 'sync layer'.
Caching of requests via service workers only goes so far, and isn't as reliable as browser storage.
The planned long term goal for us would be submissions stored in PGLite via OPFS storage, then either:
electric-sql as the sync layer to a central postgres instance, with a trigger to update in Central.
when connectivity is restored, send locally stored submissions one by one.