IDEMSInternational / open-app-builder

PLH App Frontend
GNU General Public License v3.0
6 stars 25 forks source link

[BUG] User ID value is changes after uninstalling and reinstalling app on iOS #2366

Open jfmcquade opened 2 months ago

jfmcquade commented 2 months ago

Describe the bug

It was reported that after uninstalling and reinstalling the plh_facilitator_mx app on iOS, the unique User ID value (stored in the protected app_user_id field) had changed.

This issue would be less likely to be encountered if the iOS in-app updates feature was functioning as expected (see #2365) – it was only noticed because a user was forced to uninstall and reinstall the app in order to update to the latest version. However, the issue would still persist.

App version

v0.16.33

The template debug_calc_context_variables can be used to view the current user ID.

Additional context

We use Capacitor's Device.getId() API to generate a uuid for each user. The underlying method varies by device, and as noted by the Capacitor developers, on iOS:

The value in this property remains the same while the app (or another app from the same vendor) is installed on the iOS device. The value changes when the user deletes all of that vendor’s apps from the device and subsequently reinstalls one or more of them.

Possible fixes

I can think of a few different options for handling this issue:

Keychain/secure storage

Data stored by an app in the iOS "keychain" does persist after uninstalling and reinstalling an app. We could use the capacitor-secure-storage-plugin to store the user's ID in the keychain on iOS, and perform a check on initial app launch as to whether they already have a UUID stored in the keychain, using the pre-existing one if it is found.

This should provide the expected functionality without requiring any authoring changes or any action from the user.

There is some suggestion that the user could bypass this data persistence if they choose the "delete my data" option when uninstalling the app.

Request users to remember their own ID

One option would be to request that users make a note of their UUID and store this in a safe place. Then, on initial app launch, we could encourage the user to pick up where they left off with a prompt like "Have you previously installed the app? If so, enter your ID here". However, requiring that users hang on to their UUID does not seem desirable or realistic.

Log in and automatic sync

Perhaps the most thorough way to handle issues like this would be to have users log in with a username and password that could be associated with their data on our backend. This would facilitate users accessing their data across reinstalls (and potentially across multiple devices). However, requiring that a user sets up a username and password is additional friction that we likely want to avoid, and managing this feature on the backend could be difficult (for example, a user logged in on multiple devices could update their data from two different sources, potentially requiring a merge strategy on the back end to avoid losing data).

chrismclarke commented 2 months ago

Each of the 3 options present different problems (all solvable, but still additional problems)

Keychain

Memory If wanting something memorable then we can't rely on UUIDs as these are just not (and easy to lose what is written down) - so really we would then want to move over to a username-based login which arguably adds more friction to a more simple google/apple auth login system

Login and sync Has a small amount of friction (although at least on android can just select the actively logged in user), however more importantly it removes user anonymity which may be vital for some apps that deal with sensitive information

Of these 3 options I'd say the best is probably keychain, and then work out some means to identify multiple devices. Alternatively another option would be:

External Storage Simply write the user data to a backup file and store outside of the app data folder for recovery (e.g. plh_profile_backup.json or similar). On first load can check if device has backup file to import data from. For IOS should be able to store in the Documents directory,

On Android a little more tricky as it seems like Android 12 appears to have removed most support for external storage (https://stackoverflow.com/a/70692233/5693245), although according to android docs if an app did create it's own files and was uninstalled it should still be able to access post reinstall. So we would likely need to test across most android versions

https://capacitorjs.com/docs/apis/filesystem#directory