identity – Least invasive way to uniquely identify Android user-ThrowExceptions

Exception or error:

How can you uniquely identify a user who has installed your app so that:

  1. You will know it is them if they delete and reinstall your app;
  2. You will know it is them if they install your app on a second device they intend to use simultaneously?

Just as an example, I see that the Netflix app will automatically link to your desktop account without any user interaction. I’m guessing that they use accountManager.getAccounts() or similar method, because they also require the GET_ACCOUNTS permission. But of course that permission is marked as Protection level: dangerous. Is there any technique to do this that is less invasive or potentially alarming?


The key to answering this is to be both simple (for the user) and minimally invasive. Android provides heaps of ways to identify users and many of those ways involve piercing a user’s privacy, and if that is the only way, I will do what I do now (optional email registration). I just want a way for my app to know if a user already is registered in my system across installs without having to interview the user (username/password, email address, third-party OAuth, etc).

My main reasons are:

  1. I don’t want support requests from users who orphaned their content after a reinstall; and
  2. I don’t want to host lots of orphaned content.
How to solve:

Have a look at Firebase Authentication. It’s quite seamless and does not require much effort to incorporate. Also it does not feel intrusive or cumbersome to the end user.

Here is a video tutorial by Google.

EDIT:
In case your users are sure to have a cellular device with a phone number, you can use AccountKit. It is also what they call OTA (One Time Authentication). AccountKit uses just the users phone number to verify and validate users.

EDIT:
Firebase Authentication now features ‘Phone Verification’ which is similar to AccountKit mentioned above. Both are good services. However, Firebase phone verification lets you make your own UI from scratch (which means a lot better control than AccountKit). Also, if you don’t want to make your UI, you can always use FirebaseUI

###

i have implemented something that seems little similar to your thing by push notification , i can get error if user uninstalled my app(and from the registration id i get the user) , and if he re installed he obtain a new registration id , and try to get the user UUID for different devices

###

I think the simplest way would be using UUID and storing the hash on sharedPreferences. You should generate the UUID as earlier as possible in your app.

sharedPrefs = context.getSharedPreferences(APP_SHARED_PREFS,Activity.MODE_PRIVATE);
if (sharedPrefs.getString("YOUR-KEY-TO-THE-UUID") == null || "".equals(sharedPrefs.getString("YOUR-KEY-TO-THE-UUID"))){
    prefsEditor = sharedPrefs.edit();
    prefsEditor.putString("YOUR-KEY-TO-THE-UUID", UUID.randomUUID().toString());
    prefsEditor.commit();
}

###

I think that the best way would be implementing login with Google or Facebook. This is quite seamless for users, safe enough (as Google and Facebook considered trusted), you do not need to implement your email registration and you will have identity across devices.

###

If your app is Android only and you’d like to provide identity without any account creation for the user, I believe using Google Account name/id is the best choice (Accessing Google Account Id /username via Android) since you have to use Google Account on Android phone (unless you root it, delete Google Play Services etc).

If you’d like to only address the first point of your question (identify after reinstall) there’s a Device Id –Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID);
though it’s not 100% reliable (f.e Factory Reset resets this value)

###

The standard for achieving this sort of functionality is through the use of JSON web tokens (JWT) in conjunction with standard restful api traffic.

Assuming your android application interacts with a RESTful api for all crudlike operations and business logic, then using a JWT as an authentication identifier to your api can work quite well. You can embed information in each JWT allowing you to identify whatever you like (the user id in the database, the device id of whereve the user logged in from, etc). A JWT is essentially a datastructure allowing you to store information to be used by the API.

Some basics for how this works:

  1. Getting the JWT into the app: A user logs in to the application using their username/password. The
    api then returns an encrypted JWT to be used by the client for all future requests. Don’t try to do
    the encryption yourself. Any language that can handle serving an api
    will have libraries for this.
  2. Using information in the JWT: The JWT is itself a datastructure. For example, it might look like this:

    {
    user_id: 1,
    device_id: 44215,
    device_os: android,
    }

    Your api will decrypt the JWT when it is supplied for
    authentication via the request header, and then have that information available in the
    context of the session.

If you provide the language used by your api then I might be able to recommend a library.

I will conclude by referring to the final requirement you submitted which states essentially that you do not want to have to interview the user across installs. If I understand your meaning, that you want a user to be able to simply install the application and begin using it without supplying authentication credentials, then there is no way to achieve that securely. You might be able to come up with a hackish way to get it to work, but it will be fundamentally insecure.

Leave a Reply

Your email address will not be published. Required fields are marked *