Skip to content
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

Closed
shankari opened this issue Mar 27, 2019 · 10 comments · Fixed by e-mission/e-mission-server#687

Comments

@shankari
Copy link
Contributor

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.

@shankari
Copy link
Contributor Author

There are two basic fixes possible, for short-term surveys with one-time confirmation:

  1. add a button for users to say that the confirmation is done and should be uploaded: this will basically force start and force end a trip and then force sync. I believe I added such a button for the cci project, but I have to find it again. We should also think about where this button should be. For the cci project, the button was in the profile screen, which was fine because they had researchers going out into the field and interacting with participants at the survey end. But it is probably not a great fit for all surveys
  2. change the mode and purpose confirmation buttons to make synchronous calls to the server: This is likely to lead to a more network/data traffic because we make a call for every confirmation, but it means that we don't need to add any more buttons.

@shankari
Copy link
Contributor Author

@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.

@shankari
Copy link
Contributor Author

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.

@shankari
Copy link
Contributor Author

@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.

@shankari
Copy link
Contributor Author

Aha! The change is in this commit
e-mission/e-mission-phone@432ad79#diff-4d885945fac2ff7e87409a72f748df51

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.

@shankari
Copy link
Contributor Author

@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.

@shankari
Copy link
Contributor Author

@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...

@shankari
Copy link
Contributor Author

Cherry picked the change into master in e-mission/e-mission-phone#544
(e-mission/e-mission-phone@29b3dba)

@shankari
Copy link
Contributor Author

Closing this for now since deployments can just enable this functionality if they choose to ask their users to force push.

@shankari
Copy link
Contributor Author

shankari commented May 9, 2019

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.

@shankari shankari reopened this May 9, 2019
shankari added a commit to shankari/e-mission-server that referenced this issue May 9, 2019
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.
trevor-wu added a commit to trevor-wu/e-mission-server that referenced this issue May 11, 2019
* 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.
jf87 pushed a commit to jf87/e-mission-server that referenced this issue Jun 21, 2021
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant