Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Bug Wrong documentation for PlayerName API

Discussion in 'Authentication' started by MiTschMR, Jul 25, 2023.

  1. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    401
    The documentation for getting a player name is wrong: https://docs.unity.com/authentication/en-us/manual/player-name-management#Getting_player_name

    It mentions there that
    AuthenticationService.Instance.GetPlayerNameAsync()
    returns null if no player name has been found. However, this is plain wrong, it returns a random collection of words put together! The cached value
    AuthenticationService.Instance.PlayerName
    returns null, if it has not yet been called with the Get method.

    How are we supposed to know if a user already has a player name or not?

    Used version of the Authentication SDK: 2.7.1
     
    Last edited: Jul 25, 2023
  2. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    401
    After investigating the 2.7.1 SDK version, it is indeed true that it auto generates a name!

    The
    AuthenticationServiceInternal
    's
    GetPlayerNameAsync()
    method calls the
    PlayerNamesApi.GetNameAsync(...)
    method which has the following description:

    Code (CSharp):
    1. /// <summary>
    2. /// Get a player&#39;s username. Get a player&#39;s username. The &#39;/me&#39; endpoint can be used to get the username of the calling player.
    3. /// </summary>
    4. /// <exception cref="ApiException">Thrown when fails to make API call</exception>
    5. /// <param name="playerId">The player&#39;s ID.</param>
    6. /// <param name="autoGenerate">Indicates if a player without a name should have one auto generated or not. Defaults to true. (optional)</param>
    7. /// <param name="showMetadata">If true, returns additional metadata like &#39;autoGenerated&#39; with records. Defaults to false. (optional)</param>
    8. /// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
    9. /// <returns>Task of Player</returns>
    See the
    /// <param name="autoGenerate">Indicates if a player without a name should have one auto generated or not. Defaults to true. (optional)</param>
    ?

    The method contains this check here:
    if (autoGenerate != null)


    However, the method parameter is defined like this:
    bool? autoGenerate = default(bool?)


    To my knowledge, this means that the check results to true, because false (the default value of a boolean) is not equal to null, confirming that the player name is auto generated!
     
    Last edited: Jul 26, 2023
  3. Laurie-Unity

    Laurie-Unity

    Unity Technologies

    Joined:
    Mar 5, 2020
    Posts:
    217
    The documentation relating to Gettig a Player Name was incorrect, but has now be rectified.

    Thanks for bringing this to our attention, apologies for any confusion it caused.
     
  4. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    401
    Thanks for correcting the docs, but the question still remains:

    - How do we know that this is a fresh user account in order to prompt the user for a name?

    The only option I can see is for example to try and get a cloud save key e.g. "freshAccount" and if that key doesn‘t exist prompt for a name, otherwise use the player name from the auth service.
     
  5. Laurie-Unity

    Laurie-Unity

    Unity Technologies

    Joined:
    Mar 5, 2020
    Posts:
    217
    Hi,

    The
    AuthenticationService.Instance.GetPlayerNameAsync()
    method always returns a name
    (the saved one or a randomly generated one).

    If you want to test whether this is a new player without a name, you can check the
    AuthenticationService.Instance.PlayerName
    for null, then allow the player to provide their own name instead.

    Something like
    ...
    Code (CSharp):
    1. // UPDATE PLAYER NAME FIELD DISPLAY
    2. string playerName = AuthenticationService.Instance.PlayerName;
    3. if (playerName == null)
    4. {
    5.     playerName = GetPlayerNameFromPlayer(); // ALLOW USER TO PROVIDE THEIR OWN NAME
    6.     if (playerName != null)
    7.     {
    8.         // SAVE THE NAME PROVIDED BY THE PLAYER
    9.         await AuthenticationService.Instance.UpdatePlayerNameAsync(playerName);
    10.     }
    11.     else
    12.     {
    13.         // GENERATE RANDOM NAME IF PLAYER DIDN'T PROVIDE ONE
    14.         playerName = await AuthenticationService.Instance.GetPlayerNameAsync();
    15.     }
    16. }
    ...
    Code (CSharp):
    1.     private string GetPlayerNameFromPlayer()
    2.     {
    3.         // GET NAME INPUT FROM PLAYER
    4.  
    5.         // TEST BY COMMENTING IN/OUT ONE OF THESE LINES
    6.         string playerName = null;
    7.         //string playerName = "New_Player";
    8.  
    9.         return playerName;
    10.     }
     
  6. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    401
    This is only correct if the PlayerName property is filled with the correct value upon initializing the services. From my tests a few months back (and written in my initial post) this was not the case, you had to first call the Get method to get a value at all.

    Edit: Yes, the issue is still there. The cached player name is, as its name implies, only cached upon first calling the GetPlayerName() method. If it is not called first, it will always return null.

    @Laurie-Unity your code does unfortunately not work. It also does not work if an existing user signs in on a new device. The PlayerName property will return null there.
     
    Last edited: Oct 14, 2023