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

DeviceInfo needs a way to get the ID #61

Closed
mattleibow opened this Issue Mar 5, 2018 · 29 comments

Comments

Projects
@mattleibow
Copy link
Contributor

mattleibow commented Mar 5, 2018

This may either be the unique device identifier and/or the installation Id.

APIs:

If you are leave a comment here can you please describe why and how you are using it.

@mattleibow

This comment has been minimized.

Copy link
Contributor

mattleibow commented Mar 5, 2018

This will be a good reference for the code and the issues: https://github.com/jamesmontemagno/DeviceInfoPlugin

@mattleibow

This comment has been minimized.

Copy link
Contributor

mattleibow commented Mar 5, 2018

This commit removes the potential code: 3f46dd9

Notably, the Android implementation must use Build.GetSerial() on Android O+

@Redth Redth added this to New in Triage Mar 7, 2018

@Redth Redth added this to Backlog in v0.5.0-preview Mar 12, 2018

@jamesmontemagno jamesmontemagno added this to the V2 milestone Mar 26, 2018

@Redth Redth removed this from New in Triage Mar 27, 2018

@Redth Redth modified the milestones: V2, Preview-1 Mar 27, 2018

@jamesmontemagno jamesmontemagno removed this from Backlog in v0.5.0-preview Mar 28, 2018

@mattleibow mattleibow added this to New in Triage Mar 29, 2018

@Redth Redth modified the milestones: Preview-1, V2 Mar 29, 2018

@cklenk

This comment has been minimized.

Copy link

cklenk commented May 18, 2018

This would be great to have! Thanks.

@Im-PJ

This comment has been minimized.

Copy link

Im-PJ commented May 19, 2018

yes its needed. that's why im not able to switch from device info plugin.

@Mrnikbobjeff

This comment has been minimized.

Copy link
Contributor

Mrnikbobjeff commented Jul 6, 2018

A device id has a plethora of different usage scenarios. I would love love love seeing this added.
For UAP we could use the rather newly introduced SystemInformat Type. iOS would probably use the UUID.
I believe the implementation to be very straight forward, so this would be an easy improvement with a high payoff.

@aherrick

This comment has been minimized.

Copy link

aherrick commented Jul 6, 2018

@Mrnikbobjeff I don't believe you can programatically get the UDID on iOS.

@jamesmontemagno

This comment has been minimized.

Copy link
Collaborator

jamesmontemagno commented Jul 6, 2018

@aherrick @Im-PJ @cklenk we would love to know how you are using it so we can get the API correct as they are very different between each platform.

@Im-PJ

This comment has been minimized.

Copy link

Im-PJ commented Jul 8, 2018

once user registers on app on certain device, i was storing device id and doing a check on each login. if the device id is different user is not allowed to login and have to register again. this was to control that company app is being used by user on his device only. basically i need unique device id which doesn't change atleast till the device is reset or OS re-installed.

@Mrnikbobjeff

This comment has been minimized.

Copy link
Contributor

Mrnikbobjeff commented Jul 8, 2018

@aherrick You are correct, apparently the best we could do would be DeviceIdentifierForVendor, which should be sufficient for most purposes

@cklenk

This comment has been minimized.

Copy link

cklenk commented Jul 24, 2018

@jamesmontemagno I was using it for licensing purposes, keeping track of a device a user has to enable or disable based on the number of licenses someone had. Thank you for your work!!

@domagojmedo

This comment has been minimized.

Copy link
Contributor

domagojmedo commented Jul 26, 2018

This would be really nice to have like in @jamesmontemagno DeviceInfoPlugin

@jamesmontemagno jamesmontemagno added this to the 0.10.0-preview milestone Jul 26, 2018

@Mrnikbobjeff

This comment has been minimized.

Copy link
Contributor

Mrnikbobjeff commented Jul 26, 2018

Would we need to make this async? On android this requires READ_PHONE_STATE if you use Build.GetSerial()

@jamesmontemagno

This comment has been minimized.

Copy link
Collaborator

jamesmontemagno commented Jul 30, 2018

Introduction of two APIs:

string IdForVendor { get; }
Task<string> GetSerialAsync();

IdForVendor

Represents an Alphanumeric string that uniquely identifies a device to the app's vendor. The value of this property is the same for apps that come from the same vendor running on the same device. A different value is returned for apps on the same device that come from different vendors, and for apps on different devices regardless of vendor.

On Android this will always be unique per app per device.

GetSerialAsync()

This method will attempt to get the system's serial hardware identifier or a unique quid for that system.

  • Android: Requires READ_PHONE_STATE Permission. On Android API 26+ Uses Build.GetSerial(), on lower will use Build.Serial, and as fallback will use AndroidId from secure android provider settings
  • iOS: on iOS 11+ will use device check to generate a unique token for the device. On < iOS 11 will generate a unique NSUUID and for each of these will store into NSUserDefaults to persist.
  • UWP: Uses HardwareIdentification.GetPakageSpecificToken
@Redth

This comment has been minimized.

Copy link
Member

Redth commented Jul 30, 2018

  1. I think for Android to store a random UUID we'd need to do something a bit differently internally here to share the preferences between other apps by the vendor (likely at that point with a shared keystore or something) - this seems like it's not going to be easy to have a unique ID per device per developer (per device per app is certainly attainable).

  2. I'm confused about the different approach for each property for iOS, it seems like UIDevice.IdentifierForDevice does what we want for both API cases? Why are we using Device Check on the second API?

@jamesmontemagno jamesmontemagno removed this from the 0.10.0-preview milestone Aug 16, 2018

@freever

This comment has been minimized.

Copy link

freever commented Sep 1, 2018

Correct me if I'm wrong, but iOS DeviceCheck only allows you to store two bits of information, so it won't be able to store a string.

@jamesmontemagno

This comment has been minimized.

Copy link
Collaborator

jamesmontemagno commented Sep 4, 2018

Yeah, I don't think that is good reading further: https://developer.apple.com/documentation/devicecheck

I don't know or think that this API should be introduced as it is nearly impossible to get correct.

@freever

This comment has been minimized.

Copy link

freever commented Sep 4, 2018

Yeah I guess if an API can't behave predictably it's not worth having.

For my app it is quite important to remember a device's identity between installs so I've implemented a hand rolled hack. It does allow me to retrieve the same ID even if the app is deleted and reinstalled, but I'm not live yet so I;m not sure if Apple will object.

public string GetId()
        {
            if (string.IsNullOrEmpty(_id))
            {

                var idRecord = new SecRecord(SecKind.GenericPassword);
                idRecord.Generic = NSData.FromString("myId");
                var matchingIdRecord = SecKeyChain.QueryAsRecord(idRecord, out  var idResult);
                if (idResult == SecStatusCode.Success)
                {
                    _id = matchingIdRecord.ValueData.ToString();
                }
                else
                {
                    _id = System.Guid.NewGuid().ToString();

                    var newIdRecord = new SecRecord(SecKind.GenericPassword)
                    {
                        ValueData = NSData.FromString(_id),
                        Synchronizable = false,
                        Generic = NSData.FromString("myId")
                    };

                    var saveResponse = SecKeyChain.Add(newIdRecord);

                    if (saveResponse != SecStatusCode.Success && saveResponse != SecStatusCode.DuplicateItem)
                    {
                        _id = UIKit.UIDevice.CurrentDevice.IdentifierForVendor.AsString();
                    }
                }
            }
            return _id;
        }
@jamesmontemagno

This comment has been minimized.

Copy link
Collaborator

jamesmontemagno commented Sep 4, 2018

Essentials here could be used to do all of the Keychain stuff... See SecureStorage as it does all of this. You would only need a way to get the IdentifierForVender, however it is not really reliable as it can change based on how many apps you have installed in general.

Know though that the keychain is transfered over to new devices so the new device would have the same GUID.... so not sure if that is what you are looking for.

I think that is the problem with the "ID" is that developers will want to use it in different ways. Hard for us to give a consistent API across all platforms.

The concept though of doing this would work for you:

var id =await SecureStorage.GetAsync("my_id");
if(id == null)
{
   id = System.Guide.NewGuid().ToString();
  await SecureStorage.SetAsync("my_id", id);
}
@freever

This comment has been minimized.

Copy link

freever commented Sep 4, 2018

@jamesmontemagno

This comment has been minimized.

Copy link
Collaborator

jamesmontemagno commented Sep 6, 2018

After examining this API we have come to the conclusion that it is not a good fit for Essentials as it can not be properly abstracted across each platform. Documentation has this in place today to outline how to do this via platform specific code.

Triage automation moved this from New to Closed Sep 6, 2018

@15mgm15

This comment has been minimized.

Copy link

15mgm15 commented Sep 20, 2018

@jamesmontemagno If we need still a unique ID what should be the correct approach? IdForVendor ?

@jamesmontemagno

This comment has been minimized.

Copy link
Collaborator

jamesmontemagno commented Sep 24, 2018

you could probabloy use this: #61 (comment)

however, i would read the ios/android/uwp specific docs and recommendations on how to do this. Android has some new support packages that could handle this somehow, however it is really hard to ever ensure that the same exact ID will come back.

@gitown

This comment has been minimized.

Copy link

gitown commented Nov 10, 2018

@jamesmontemagno please to take a look at the Unity3D docs, they're able to provide a DUI for almost all platforms (with the exception of iOS which provides a new identifier when the app is reinstalled): https://docs.unity3d.com/ScriptReference/SystemInfo-deviceUniqueIdentifier.html
As an old Unity3D developer, I can say that this feature is really important!
One of the uses case of the DUI: we can save the settings of the app on the cloud using the DUI, if the user uninstall and install the app again, the settings can be retreived form the server using the DUI (especially for Android and UWP).

@Redth

This comment has been minimized.

Copy link
Member

Redth commented Nov 11, 2018

Those docs don't seem to mention how they do things on android which is perhaps the trickiest platform and would require taking additional dependencies we are trying to avoid...

@gitown

This comment has been minimized.

Copy link

gitown commented Nov 12, 2018

Those docs don't seem to mention how they do things on android which is perhaps the trickiest platform and would require taking additional dependencies we are trying to avoid...

Here is a thread with more details about how they're getting the DUI for Android: https://forum.unity.com/threads/unique-identifier-details.353256/
and
https://stackoverflow.com/a/44147543

@jamesmontemagno

This comment has been minimized.

Copy link
Collaborator

jamesmontemagno commented Nov 12, 2018

Although now on Android 8.0+ ANDROID_ID actually returns different values then before. Reading through the code which I already did and outlined there truly isn't a consistent and accurate way to get the Device ID across all platforms. There are many different paths that the code can take, permissions needed, and errors that can come from this.

How developers are looking to use this data is often for payment information or other authentication purposes. Since there is not stable API across all platforms this means that Xamarin.Essentials can not provide this API to developers for such a critical part of their application and we will leave it up to each developer to decide what native APIs they want to take a reliance on to calculate this information.

@gitown

This comment has been minimized.

Copy link

gitown commented Nov 12, 2018

I understand your point of view, but I still think that this feature is very important for developers and will save us lot of time if it will be available out of the box in Xamarin.Essentials!
About the ANDROID_ID, I just read the documentation and found that it returns a consistent and unique value for the combination user/app/device, even if the user uninstall/reinstall the app, unless he decide to wipe or upgrade his device, and I find that this is an acceptable behaviour.
I hope you'll keep considering this feature in a future release of Xamarin.Essentials. And why not creating a poll on your upcoming features to see which of them are more important to your community and then prioritize them.

@AngeloLazzari

This comment has been minimized.

Copy link

AngeloLazzari commented Nov 17, 2018

Firstly: THANK YOU A LOT GUYS for the really unbelievable work you do creating and mantaining plugins that millions of people use with our apps.

My situation is this one, i had using plenty of different nugets to get all the Essentials plugin do all in one... the last one i was "cleaning" was the CrossDeviceInfo that i was using to get the device platform and i substituted with the Essentials DeviceInfo ..... good work... BUT, in just in my app i used CrossDeviceInfo.Current.Id, and i really expected to find the Essentials property too, BUT...SURPRISE!! ... no way to get it. So now i have to keep the CrossDeviceInfo just to get the ID....

My need is not to have a 100% UUID, but just an ID that linked with another realtime info of the app will keep the entire ID as "unique" in my "app world"...

i think, just to get things "linear and clean" and not have nuget installed just for one property use, Essetials could give the same ID value as CrossDeviceInfo do....

Those were my two cents....
thank you very much

@AnEnglishmanInNorway

This comment has been minimized.

Copy link

AnEnglishmanInNorway commented Nov 29, 2018

I have to agree with Angelo - first in really appreciating the all the work which allows me to stand on others' shoulders rather than reinventing the wheel, and second in being really surprised by the lack of an equivalent for Plugin.DeviceInfo.Abstractions.IDeviceInfo.Id in Xamarin.Essentials.DeviceInfo. I have exactly the same need - a unique key for this particular device. If we found a good use for it in James's old plugin, why couldn't we have the same thing in the new one. By all means with a caveat in the documentation.
Please? So I don't have to keep using the old plugin?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment