I would like to publish an Android app with 2-years time support (this is due to API costs). After 2 years, the user has to buy the app again (if he wants).
There are at least 3 problems:
I want it to be easy and effortless for the user: so no "registration form" (if possible).
The app should work on other devices connected with the same Google account (as every payed app).
The app should not work if the user sells his device: so using device's IMEI isn't a very good solution.
I think that the definitive solution would be univocally identifying the user, but the question is: how to do that?
Do you think that AccountManager could be a solution?
Note that the app needs to connect to my server in order to work, so the solution can be implemented both client and/or server side.
You can try to uniquely identify the user using his/her phone number. This is what Wavesecure does.
This does have some implications:
a) your app cannot work on a wifi only tablet.
b) you will have to provide a way for users to migrate phone numbers in case they happen to change phones.
You said that:
The app should work on other devices connected with the same Google account (as every payed app).
Use the google account.
When the app starts have him choose a google account and save the account ID (the email address) server side.
Also make sure the user can change the referenced account, it should not make any difference, as long as you allow just one account per user.
Ideally, as time passes by, you may want to track the active installations for each user, and limit the number of devices (model name, IMEI if available, OS version etc) to prevent fake account sharing. But that's something you can do later.
Related
I am creating an iOS and Android App and I want to create a screen where the player can start with a guest account or can connect his account with our own accountsystem.
But my question is: Can I detect a user after the app was uninstalled and installed again?
I know that there is something like the vendor. But this will change.
I know that other apps also can do this.
With the user's permission- have them log into an account. Or provide you with their google of facebook account info. So far as hardware ids, those are discouraged and actively being removed to prevent people from the API to prevent this.
Also remember- that unless the user logs in with an account, you don't really know whether it is the same person. You could know its the same phone, but you don't know if he gave it to his kid sister to play on. Or sold it when he got a new one, and now you've given the new owner access to someone else's account. Also, if you rely on hardware ids you won't know its me when I buy a new phone and download it on that.
So yeah- either have him log in with a username and password, or use a 3rd party signon mechanism like Google or Facebook.
For iOS, there is a recommended approach to do that: by using the DeviceCheck framework. The idea here is that it allows you to persist 2 bits of data across app installations on each device. You can set the first bit to 1 if the user has already installed the app or 0 otherwise. And use the second bit, for example, to check if the user has signed in or not.
The official documentation is pretty good, please check it out.
The downside of this approach is that you will also have to do some work on the backend side.
UPDATE:
If you specifically want to detect the account, there is no reliable approach. One of the options is to use identifierForVendor or generate some kind of device fingerprint (for example, by combining the device model, timezone, locale, etc.), but of course, this will not work every time.
Uniquely identifying a device is a security leak, and all platforms are putting serious restrictions on unique persistent identifiers because of privacy concerns.
My system consists of a mobile app (a Cordova app), and a webservice, providing all the relevant data. When a user buys the app in the appstore (or playstore, if android), a user account should be created on the webservice, ideally without any user interaction (no registration). The user account could be linked with the gmail account, apple id, ... This is required, to only allow people who have paid to use the webservice.
My Problems:
I did not find a way to get the user id of the user. (Android seems to have a way: https://github.com/loicknuchel/cordova-device-accounts , but iOS not).
I only want exactly one registration per user. This saves me from using something like a registration page, when the app is first started - this could easily be bypassed and lead to multiple registrations.
The user account should be linked to the user and not the device (so no device UUID or so, as this would not be portable between devices).
Ideas that I had:
(Favorite, doesn't seem to be possible) I have a method "getUserID()" in the app, which returns the right user on the phone. Additionally, I have access to an API to check who bought my App. I can easily cross check, to make sure that the user has permission to use the webservice.
(Unnecessary complicated, seems wrong) Make the app free, use a single in-app purchase to buy access to the webservice. When I searched, I found that it seems that in app purchases give you more information, so there might be the chance to link the app with a user.
(Even worse than 2.) Make the app free, use an own payment system/registration.
My question:
What does the Android/iOS app-store eco system provide, so that I can ensure that one user buying the app creates exactly one user account on my webservice, and this user account is linked to the user and not the device?
You should generate a secret api key for each paying user.
Then the user should use this key to auth into your API and get a token back (you can make it expire after some time if you want a stronger protection). User should attach this token to all of his api calls.
Scenario
The user get only the first time free credits in the app. After that we want to do fraud prevention. We need to check if the user and/or the device have not installed the application before.
We can accept the risk of a factory reset or rooted devices
What I tried already
Listen to Intent.ACTION_PACKAGE_FIRST_LAUNCH. After reading I understand that this event is only send to the Play store and can't be used in any other app.
Check the application package info for the field "firstInstallTime", this is reset when the user removed the application and do a install.
Android Backup Service, but the user can stop the backup and reset data, so this is at no use.
App licensing looks like a promise solution to detect if the user have already installed the app. But with limitations the following is described: "You can implement licensing controls for a free app, but only if you're using the service to provide APK expansion files." Do we need to make a small APK expension file, just to verify the license?"
make a fingerprint of the mac address, imei, android id and some other stuff. But would this make the scans of Google play violating? I don't use it for advertising, but i'm afraid they think we violate the google play policy.
how you can help me
Can you help me to choose a good direction to solve this issue and maybe give some better methods to do this verification.
Factory reset, second-hand phones and users with multiple devices will be your main problems.
The only way to uniquely identify a user is an authentication through login/password or OpenId account.
Hey there if you are managing user information at the your server than what you can do is take the IMEI number of the device and send it to your server. It will record the information of the user. Now if he/she uninstall and install app again your app will again send IMEI number at server now you can check the IMEI already present or not, If present then user have already installed your application, more over you can manage same thing from the login ID, but that can be faked by the user. More over it will not violate any thing. User can see while installing in the permissions that your app will get the system information.
I develop mobile cross-platform games (for iOS,Android and WP).
I want to know the email or the phone number of the people who bought my app from the iOS,Android or WP store, for using these informations for authentication purpose.
Waiting for your valuable comments and sugessions
Thanks.
You don't have that information unless people authorize you or give it to you.
Under no circumstances should you be able to get the information of the people who are buying your apps unless they opt into it and it’s made crystal clear to them that you are getting this information.
This was in the news last year because you shouldn't have that data.
This counts for iOS and Android.
options
Ask users for their personal information in the app and send it to
your servers.
Make your app need registration and login ( This is very strict on iOS, make sure you have some kind of offerable service which actually need registration)
You can link their personal information with device numbers, but these are spoofable on rooted and jailbroken devices
To get the device information on android:
You want to call android.telephony.TelephonyManager.getDeviceId().
This will return whatever string uniquely identifies the device (IMEI on GSM, MEID for CDMA).
You'll need the
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
permission to do this.
On iOS look at this answer: How to get IMEI on iPhone?
I can only speak for iOS:
You can't get email address nor phone number using iOS APIs. If you want this, you need to ask the user yourself.
Then you'd need a way to verify them:
Email by sending a link they need to click.
Phone number by sending the user an SMS (with link they need to click, or code they need to type in UI), or by calling them and asking them to dial/DTMF a code they see in the app, or on the app enter a code they hear.
If you want to keep users apart, without needing any info from them:
Have a non-consumable in-app payment item (which you could call 'account' for example). Since these items can only be bought once per user, and because Apple's in-app purchase receipt contains a unique ID, you can use this as a user identifier. (If this does not make sense, you need to read Apple's documentation about in-app purchases.)
If you are asking the user for mail/no then just store temperorly and use webservice to retrive in background
If you want the details without knowing to user Use analytics and catch maild id's of user (flurry , google analytics)
I dont think this is possible currently. The playstore console displays information like number of download, carriers, devices, etc. You may want to consider building in those features and requesting the info from the user via the valid permissions. Aside there is an unofficial playstore API that lets you pull data viz. app info, comments, etc. You can find it here
I'm designing an Android mobile application.
The application uses a credit system. The user can buy credits through the Google in app billing services.
Moreover, when the user installs the application, it gets some free credits.
The user credits are stored in a web server. When the user downloads the application, a UUID is created and stored in the app & server.
I need somehow to detect when the user uninstalls the app, and reinstalls it, in order to receive the starting free credits (reinstall will create a new UUID, so it will be like a new user).
I've been looking for a phone or user identifier, but I've read that this is not a very nice idea (http://android-developers.blogspot.com.es/2011/03/identifying-app-installations.html Is there a unique Android device ID? or How to find serial number of Android device?). Moreover, this can be hacked easy in order to use a not owned account.
Is somehow to solve this problem? Maybe using the in app billing?
I'm opened to any solution.
Thanks
As you are totally right (identifying devices is useless) I would use the Google user account to achieve people identification:
http://developer.android.com/training/id-auth/identify.html
AccountManager accountManager = AccountManager.get(getApplicationContext());
Account[] accounts = accountManager.getAccountsByType("com.google");
for (Account a: accounts) {
if (a.name.contains("#gmail.com")) {
return a.name;
}
}
This might be tricky but will allow you to identify reisntall from the same Googkle Play account that downloaded the app.
Why not to use IMEI. It's easy to get. It's hard to change and in many countries it'is illegal (to prevent phone robbery). We use it for many purposes.
And you would only need one extra permission READ_PHONE_STATE. (Most user do not complain)
In very few devices it may return NULL, in that case you should be prepared and test another unique identifiers like the Serial No. The Mac Address. Android ID or the UUID.
As you said this last identifiers are more easily hacked but since there are very few devices is less likely you have hacking problems.
The solution is more about design. By example in video games if you re install the game to get free virtual cash, you'll also be deleting your save so you'll start from zero ending up with the same amount of cash. Since there is not transfer of cash between players this cannot be exploited.
If you are providing a web service. You can also check for IP in every request. And therefore keep a track of the amount a request and the total credits. This along with IMEI.
Finally if you belive is really important, you could request a credit card (with no charge) just to prevent multiple accounts of the same user. For most services is not necessary because you will have less users and it may end up being worse.