I am trying to implement a longitudinal survey that respondents will access from their mobile phone (in an application that I have written). I would like a unique user ID so that I can link submissions that come from the same respondent, but I do not want this to contain any personal information. Ideally this would simply be a random UUID generated on the phone. Is there a way for me to insert such an ID into the form through a webview?
Alternatively is it possible to collect a hashed value of the user’s imei code? For example, could I use deviceid in the XLSForm but then hash it and collect only the hashed value?
Thanks, I am planning to use this in a mobile phone application that will run on both Android and iOS. My idea is to let users access the survey through a webview and I want to the survey to collect a unique identifier for each user that does not contain personal information.
I have just been experimenting with the digest function (https://docs.getodk.org/form-operators-functions/#utility). My idea was to have a deviceid field and then calculate the hash of this. But I am getting an error when I try to use digest:
FormLogicError: Could not evaluate: digest( /model/instance[1]/data/this_deviceid , SHA-256, base64), message: Function "{}digest" does not exist.
Would you mind sharing your xlsform with the community (deleting all the other variables and keeping only the required variables) so that we could have a look at our end and see if we could provide any inputs.
I’d be glad to help you implement a unique user ID for your longitudinal survey in the mobile app’s webview. Here are the two approaches you mentioned, along with their pros and cons:
1. Generating a Random UUID on the Phone:
Pros:
Most secure option as it doesn’t involve any device-specific information.
Easy to implement on both Android and iOS.
Cons:
Doesn’t inherently link users across device changes (if the app is reinstalled or used on a different phone).
Implementation:
Android:
Use the UUID class from the java.util package to generate a random UUID:JavaString userId = UUID.randomUUID().toString();
Inject the userId into the webview form using JavaScript:JavaString script = "javascript: document.getElementById('userId').value='" + userId + "';"; webView.loadUrl(script);
iOS:
Use the NSUUID class from the Foundation framework to generate a random UUID:Swiftlet userId = UUID().uuidString
Inject the userId into the webview form using JavaScript (similar to Android):Swiftlet script = "javascript: document.getElementById('userId').value='\(userId)';" webView.loadHTMLString(script, baseURL: nil)
2. Hashing the IMEI Code:
Pros:
Can potentially link users across device changes if the IMEI remains the same.
Cons:
Less secure as it involves device-specific information. IMEI collection might raise privacy concerns.
IMEI can be spoofed on some devices, reducing reliability.
Not available on all devices (e.g., tablets without cellular connectivity).
Implementation:
Android (Not recommended due to privacy concerns):
Be cautious about IMEI collection due to privacy implications. Check your app’s privacy policy and local regulations.
Use the TelephonyManager class (requires permission) to access the IMEI:JavaTelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); String imei = telephonyManager.getDeviceId(); // Permission required
Hash the IMEI using a secure hashing algorithm (e.g., SHA-256).
Inject the hashed IMEI into the webview form using JavaScript (similar to UUID approach).
iOS (Not recommended due to privacy concerns):
Similar to Android, IMEI access is restricted due to privacy concerns. Avoid this approach unless absolutely necessary.
Recommendation:
For most cases, using a randomly generated UUID on the phone is the preferred approach due to its security and ease of implementation. It provides anonymity while still allowing you to track individual user submissions.
You might just use the uuid() function of XLSForm, see ODK XForms Specification. With the search function of this forum xou can also find a lot of previous discussions and examples how to create uniwue IDs.