amplify-android icon indicating copy to clipboard operation
amplify-android copied to clipboard

Auth.getCurrentUser returns user sub even if user logged in with email

Open faltiska opened this issue 3 months ago • 4 comments

Before opening, please confirm:

Language and Async Model

Java

Amplify Categories

Authentication

Gradle script dependencies

    def aws_amplify_version = '2.30.1'
    coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5")
    implementation "com.amplifyframework:aws-api:$aws_amplify_version"
    implementation "com.amplifyframework:aws-auth-cognito:$aws_amplify_version"
    implementation "com.amplifyframework:core:$aws_amplify_version"

Environment information

------------------------------------------------------------
Gradle 8.14.2
------------------------------------------------------------

Build time:    2025-06-05 13:32:01 UTC
Revision:      30db2a3bdfffa9f8b40e798095675f9dab990a9a

Kotlin:        2.0.21
Groovy:        3.0.24
Ant:           Apache Ant(TM) version 1.10.15 compiled on August 25 2024
Launcher JVM:  17.0.12 (Oracle Corporation 17.0.12+8-LTS-286)
Daemon JVM:    E:\Programare\jdk-17.0.12 (no JDK specified, using current Java home)
OS:            Windows 11 10.0 amd64

Please include any relevant guides or documentation you're referencing

No response

Describe the bug

Auth.getCurrentUser returns user sub even if user logged in with email.

The AWS Mobile Client was returning the email in such cases. The javadoc said:

/**
 * Returns the username attribute of the current access token. Note that the value stored in the username
 * attribute of the access token may vary depending on how sign-in was performed. For example, if the user signed in
 * with email, the username attribute will have the email address.
 * @return The username attribute of the current access token.
 * @see <a href="https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html#amazon-cognito-user-pools-using-the-access-token">Using the Access Token</a>
 * from Cognito documentation.
 */
@AnyThread
public String getUsername() {
    try {
        if (userpoolsLoginKey.equals(mStore.get(PROVIDER_KEY))) {
            return userpool.getCurrentUser().getUserId();
        }
        return null;
    } catch (Exception e) {
        return null;
    }
}

Reproduction steps (if applicable)

No response

Code Snippet

CompletableFuture<String> future = new CompletableFuture<>();
Amplify.Auth.getCurrentUser(
          user -> future.complete(user.getUsername()),
          authException -> future.complete(null)
);

Both the user id and the username attributes in AuthUser are the user sub, regardless of how the user logged in.

Log output

// Put your logs below this line


Configuration File

No response

GraphQL Schema

// Put your schema below this line


Additional information and screenshots

No response

faltiska avatar Sep 16 '25 17:09 faltiska

HI @faltiska. I believe this is the intended behavior for Amplify, but I'll look into it and get back to you. I'm marking this as a feature request for now.

mattcreaser avatar Sep 17 '25 13:09 mattcreaser

Hi @faltiska I have some more context to share about this. It looks like this was an intentional decision in Amplify to return the username as it appears in the tokens issued by Cognito. When you sign in with an email the tokens issued by Cognito will have the username claim set to be equal to the user's sub - and indeed you can confirm in the Cognito console that is what their username is set to.

In the AWS SDK things worked a little bit differently, the AWSMobileClient would store the value used to sign in in shared preferences (see here) and then later return that as the username from the function you highlighted in the issue.

Amplify could ultimately do something similar and store the sign in ID together with the credentials, but that is not how it works today. I'll leave this open as a feature request to gather community feedback on the utility of this change. In the meantime I would suggest using the getUserAttributes API to retrieve the email address of the user.

mattcreaser avatar Sep 23 '25 17:09 mattcreaser

I do have a simple workaround. I am currently getting the email from the ID token, at login. The method to get the ID Token may be going over the network, which I wanted to avoid. So I am also storing the email it in Preferences, at login, so I can quickly access it later. This is simple enough.

But let me still try to make an argument against the decision to return the user's sub.

The definition of username is "an identification used by a person with access to a computer, network, or online service." And, since the AuthUser has both a userId and a username, it emphasizes the expectation that the username is something different than than the user id.

Even the AuthUser constructor javadoc agrees:

    /**
     * Object to represent a logged in user with its locally cached attributes.
     * @param userId A unique identifier for this user
     * @param username The username used for logging in
     */
    public AuthUser(@NonNull String userId, @NonNull String username) {
        this.userId = Objects.requireNonNull(userId);
        this.username = Objects.requireNonNull(username);
    }

faltiska avatar Sep 24 '25 06:09 faltiska

I agree. This decision was made before my time and I don't have a lot of additional context on what the reasoning was. We cannot change the username value at this point as it would potentially be a breaking change, but there are several other options for how we could surface this information. Let me chat about this with the team and get back to you.

mattcreaser avatar Sep 24 '25 13:09 mattcreaser