Collect: Form updates and versioning
admbtlr opened this issue · comments
User Stories
As an administrator, I want to be able to specify that surveyors should be using the latest version of the relevant form so that I have some assurance about the quality of data that is being collected
As a surveyor, I want to know that I am using the latest version of the form that I am filling so that I don't waste time with unnecessary questions
As a surveyor, I don't want to have to care about form versions so that I can focus on the process of data collection
Proposed Implementation
It's easy enough to ascertain the latest version of a given form by making a call (e.g. to /formList
, but there might be a better endpoint?) to an Aggregate server. For this reason, it would make sense to implement this as a "pull" in Collect, rather than trying to do any kind of push from Aggregate.
ODK Collect should poll the endpoint every X seconds (600?), checking whether the returned version number is higher than that of the forms that are currently stored on the device. This polling should only occur when the application is running in the foreground. Future implementations might explore the possibility of having this run as a background service (payoff: complexity + data usage vs timeliness of updates).
Two measures that could be implemented to save network traffic:
- If there are multiple forms from the same Aggregate server, only one request to
/formList
should be made - Clients could cache the formList XML and corresponding manifest XML and use either ETag or Last-Modified headers when making the polling requests.
However it is suggested that too much premature optimisation should be avoided; once the feature is implemented, we can assess the impact and decide whether traffic-reduction measures are necessary.
Options
There should be a new option, "Check for new form versions when the app is in the background", which should be set to false
by default. If set to true
, there should be an additional frequency option with values of 15, 30 or 60 minutes. If these times end up being absolute (e.g if "60 minutes" translates to "on the hour"), a random number of up to 600 seconds should be added, to avoid a synchronised hammering of the server.
There should be another new option added to ODK Collect called "Automatically download new versions of forms when they become available", which should be set to false
by default.
If this option is false and a new version of one (or more) of the forms on the device is available, we should show an alert saying something like, "A new version (v20180306) of the form Household Survey is available. You currently have v20180218. Download and install the new version?" [Yes/No]
In the (fairly unlikely) case that there are multiple form updates available, multiple alerts should be shown, one per updated form.
If the "Check for new form versions when the app is in the background" option is set to true
but the "Automatically download new versions of forms when they become available" option is set to false
, users should receive one (and only one) Android notification informing them that a new form version is available. This notification should say something like, "A new version of the form
If the "Automatically download new versions of forms when they become available" option is set to true
, the forms should be downloaded and installed without informing the user.
Older form versions
Older versions of forms should be kept on the device so that filled forms that were created with an older version can still be viewed, but they should not be shown in the UI: only the latest version of each available form should be displayed and selectable.
If there are no filled forms on the device that were created with an obsolete version of a form, and a newer version of that form has been downloaded to the device, then the obsolete version can safely be removed.
Useful links
- getodk/collect#1700 - grzesiek2010's recent PR for a background service
- onaio/collect#28 - a similar issue at Ona
Follow-up issues to address once this has been implemented
- what should happen if a form that used to be in the formList is no longer in the formList?
- can/should polling be used for arbitrary text notifications?