-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Asking users for mode and purpose confirmation at the end of a study is problematic #351
Comments
There are two basic fixes possible, for short-term surveys with one-time confirmation:
|
@deepalics0044 @ipsita0012 I just realized this issue after we got off the call today. Assuming you are still going to tell people to select the mode and purpose confirmations in a batch at the end, you absolutely need to resolve this ASAP on production. If you can tell people to confirm as soon as a trip is done, it is less urgent. |
I'm looking for my prior implementation of startStopForceSync or something like that, and I can't find it easily. Still looking, may just write one if we need it. |
@ipsita0012 can you please decide which option you prefer for #351 (comment) or whether you are going to change the instructions? I don't think @deepalics0044 will be able to get to this in time, so I will make the change once you decide. |
Aha! The change is in this commit It looks like I originally made it on the cci-berkeley branch but it got lost during some of the merges to and from master. Will cherry-pick it to master, irrespective of the outcome of this issue since it is a useful debugging tool to have. |
@ipsita0012 if you go with option (1) which is probably the easiest to implement, would be good to know where the "Done confirming" button should be. Again easiest to implement will be in the profile, which is why the current implementation puts it there, but that may not be best from a UX perspective. |
@deepalics0044 @ipsita0012 FYI, while testing e-mission/e-mission-phone#542 I realized that this button is in fact enabled in the cistup-ec branch. It is in the developer zone (https://github.com/e-mission/e-mission-phone/blob/cistup-ec/www/templates/control/main-control.html#L109). Should be pretty trivial to move it out of the developer zone into the top set of controls... |
Cherry picked the change into master in e-mission/e-mission-phone#544 |
Closing this for now since deployments can just enable this functionality if they choose to ask their users to force push. |
A better option would be to synchronously save the confirmation objects while the app is in the foreground and the user is editing them. I can check in a function to enable that. |
This is intended for **foreground use only**, primarily to synchronously save user inputs in case we need it for server-specific services (e.g. generating a suggestion) or in case we want to ensure that the data is saved before the app is uninstalled. Since it is used in the foreground, users can be interactively notified if the save failed. In order to reduce abuse for sending background sensed data, this can accept one entry at a time. For client integrators, as you can see, this is similar to `/profile/update`, but the data is under `the_entry` instead of `update_doc` Testing done: We have 76 entries ``` In [16]: edb.get_usercache_db().find({"metadata.key": "manual/mode_confirm"}).count() Out[16]: 76 ``` We save one more ``` In [17]: test_input = { ...: "user": "test_mode_purpose", ...: "the_entry" : { ...: "metadata": {"key": "manual/mode_confirm", "write_ts": 12345678, "type": " ...: message"}, ...: "data": {"start_ts": 1234, "end_ts": 5678, "label": "pogo_sticking"} ...: } ...: } In [18]: requests.post("http://localhost:8080/usercache/putone", data=json.dumps(test_in ...: put), headers=headers) Out[18]: <Response [200]> ``` ``` START 2019-05-08 19:17:35.633951 POST /usercache/putone END 2019-05-08 19:17:35.649836 POST /usercache/putone 49e72fc4-f1d8-4f4d-9666-57dc597d1133 0.015433073043823242 ``` We now have 77 entries ``` In [19]: edb.get_usercache_db().find({"metadata.key": "manual/mode_confirm"}).count() Out[19]: 77 ``` and the new one is the right one ``` In [20]: edb.get_usercache_db().find({"metadata.key": "manual/mode_confirm", "data.label ...: ": "pogo_sticking"}).count() Out[20]: 1 In [21]: edb.get_usercache_db().find_one({"metadata.key": "manual/mode_confirm", "data.l ...: abel": "pogo_sticking"}) Out[21]: {'_id': ObjectId('5cd38dbfbe04ee70f576335d'), 'data': {'end_ts': 5678, 'label': 'pogo_sticking', 'start_ts': 1234}, 'metadata': {'key': 'manual/mode_confirm', 'type': 'message', 'write_ts': 12345678}, 'user_id': UUID('49e72fc4-f1d8-4f4d-9666-57dc597d1133')} ``` This also fixes e-mission/e-mission-docs#351 in a more principled way.
* Add a new method to store data synchronously This is intended for **foreground use only**, primarily to synchronously save user inputs in case we need it for server-specific services (e.g. generating a suggestion) or in case we want to ensure that the data is saved before the app is uninstalled. Since it is used in the foreground, users can be interactively notified if the save failed. In order to reduce abuse for sending background sensed data, this can accept one entry at a time. For client integrators, as you can see, this is similar to `/profile/update`, but the data is under `the_entry` instead of `update_doc` Testing done: We have 76 entries ``` In [16]: edb.get_usercache_db().find({"metadata.key": "manual/mode_confirm"}).count() Out[16]: 76 ``` We save one more ``` In [17]: test_input = { ...: "user": "test_mode_purpose", ...: "the_entry" : { ...: "metadata": {"key": "manual/mode_confirm", "write_ts": 12345678, "type": " ...: message"}, ...: "data": {"start_ts": 1234, "end_ts": 5678, "label": "pogo_sticking"} ...: } ...: } In [18]: requests.post("http://localhost:8080/usercache/putone", data=json.dumps(test_in ...: put), headers=headers) Out[18]: <Response [200]> ``` ``` START 2019-05-08 19:17:35.633951 POST /usercache/putone END 2019-05-08 19:17:35.649836 POST /usercache/putone 49e72fc4-f1d8-4f4d-9666-57dc597d1133 0.015433073043823242 ``` We now have 77 entries ``` In [19]: edb.get_usercache_db().find({"metadata.key": "manual/mode_confirm"}).count() Out[19]: 77 ``` and the new one is the right one ``` In [20]: edb.get_usercache_db().find({"metadata.key": "manual/mode_confirm", "data.label ...: ": "pogo_sticking"}).count() Out[20]: 1 In [21]: edb.get_usercache_db().find_one({"metadata.key": "manual/mode_confirm", "data.l ...: abel": "pogo_sticking"}) Out[21]: {'_id': ObjectId('5cd38dbfbe04ee70f576335d'), 'data': {'end_ts': 5678, 'label': 'pogo_sticking', 'start_ts': 1234}, 'metadata': {'key': 'manual/mode_confirm', 'type': 'message', 'write_ts': 12345678}, 'user_id': UUID('49e72fc4-f1d8-4f4d-9666-57dc597d1133')} ``` This also fixes e-mission/e-mission-docs#351 in a more principled way. * Add support for the new destination_confirm class Changes include: - new wrapper class - formatters for the input processing This is also hopefully a nicer, shorter, self-contained example of how to add new manually reported objects to the server.
This is intended for **foreground use only**, primarily to synchronously save user inputs in case we need it for server-specific services (e.g. generating a suggestion) or in case we want to ensure that the data is saved before the app is uninstalled. Since it is used in the foreground, users can be interactively notified if the save failed. In order to reduce abuse for sending background sensed data, this can accept one entry at a time. For client integrators, as you can see, this is similar to `/profile/update`, but the data is under `the_entry` instead of `update_doc` Testing done: We have 76 entries ``` In [16]: edb.get_usercache_db().find({"metadata.key": "manual/mode_confirm"}).count() Out[16]: 76 ``` We save one more ``` In [17]: test_input = { ...: "user": "test_mode_purpose", ...: "the_entry" : { ...: "metadata": {"key": "manual/mode_confirm", "write_ts": 12345678, "type": " ...: message"}, ...: "data": {"start_ts": 1234, "end_ts": 5678, "label": "pogo_sticking"} ...: } ...: } In [18]: requests.post("http://localhost:8080/usercache/putone", data=json.dumps(test_in ...: put), headers=headers) Out[18]: <Response [200]> ``` ``` START 2019-05-08 19:17:35.633951 POST /usercache/putone END 2019-05-08 19:17:35.649836 POST /usercache/putone 49e72fc4-f1d8-4f4d-9666-57dc597d1133 0.015433073043823242 ``` We now have 77 entries ``` In [19]: edb.get_usercache_db().find({"metadata.key": "manual/mode_confirm"}).count() Out[19]: 77 ``` and the new one is the right one ``` In [20]: edb.get_usercache_db().find({"metadata.key": "manual/mode_confirm", "data.label ...: ": "pogo_sticking"}).count() Out[20]: 1 In [21]: edb.get_usercache_db().find_one({"metadata.key": "manual/mode_confirm", "data.l ...: abel": "pogo_sticking"}) Out[21]: {'_id': ObjectId('5cd38dbfbe04ee70f576335d'), 'data': {'end_ts': 5678, 'label': 'pogo_sticking', 'start_ts': 1234}, 'metadata': {'key': 'manual/mode_confirm', 'type': 'message', 'write_ts': 12345678}, 'user_id': UUID('49e72fc4-f1d8-4f4d-9666-57dc597d1133')} ``` This also fixes e-mission/e-mission-docs#351 in a more principled way.
We currently store mode and purpose confirmation into the usercache just like all other data, and it is pushed to the server at the end of the next trip. This is a good fit for robust, ongoing data collection, where users confirm their trips as the trips are complete and the data will be eventually pushed irrespective of network failures.
However, it is not a great fit for a short-term survey where users are asked to confirm all the trips for the survey at the end. Effectively, once they confirm, the data will be in the usercache, waiting for them to finish the next trip to upload. But this is the end of the survey period, so they will uninstall the app immediately, and there will be no further trip ends, and the data will be deleted along with the app.
The text was updated successfully, but these errors were encountered: