Aws-sdk-ios: Retrieving AWS Credentials using AWSMobileClient

Created on 24 Oct 2019  Â·  6Comments  Â·  Source: aws-amplify/aws-sdk-ios

Describe the bug
AWS Credentials are nil.

To Reproduce

I am initializing mobile client via configuration object and get user state successfully.

let mobileClient = AWSMobileClient(configuration: configuration)
        mobileClient.initialize { (userState, error) in
            if let userState = userState {
                switch(userState){
                case .signedIn:
                    print(AWSMobileClient.default().identityId)
                case .signedOut:
                    self.signIn()
                default:
                    AWSMobileClient.default().signOut()
                }

            } else if let error = error {
                print(error.localizedDescription)
            }
        }

After signIn successfully get oidc tokens.

func signIn() {
        AWSMobileClient.default().signIn(username: "username", password: "password") { (signInResult, error) in
            if let error = error  {
                print("\(error.localizedDescription)")
            } else if let signInResult = signInResult {
                switch (signInResult.signInState) {
                case .signedIn:
                    print(AWSMobileClient.default().identityId)
                    self.getTokens()
                case .smsMFA:
                    print("SMS message sent to \(signInResult.codeDetails!.destination!)")
                default:
                    print("Sign In needs info which is not et supported.")
                }
            }
        }
    }

Getting OIDC Tokens

func getTokens() {
        AWSMobileClient.default().getTokens { (tokens, error) in
            if let error = error {
                print("Error getting token \(error.localizedDescription)")
            } else if let tokens = tokens {
                print(tokens.accessToken!.tokenString!)
                self.getAWSCredentials()
            }
        }
    }

After that I want to take my AWS Credentials

func getAWSCredentials() {
        AWSMobileClient.default().clearKeychain()
        AWSMobileClient.default().getAWSCredentials { (credentials, error) in
            if let error = error {
                print("\(error.localizedDescription)")
            } else if let credentials = credentials {
                print(credentials.accessKey)
            }
        }
    }

But it returns error;

â–¿ some : AWSMobileClientError
â–¿ cognitoIdentityPoolNotConfigured : 1 element
- message : "There is no valid cognito identity pool configured in awsconfiguration.json."

Also my AWSMobileClient.default().identityId value is nil after sign in.

Environment(please complete the following information):

SDK Version: 2.12.0
Dependency Manager: Cocoapods
Swift Version : 5.0

Device Information (please complete the following information):

Device: iPhone Xr
iOS Version: iOS 13.1.3

bug mobile client

Most helpful comment

I had the same problem
AWSMobileClient.default().identityId value is nil

AWSMobileClient.default().addUserStateListener(self) { (userState, info) in
            switch (userState) {
            case .guest:
                print("user is in guest mode.")
            case .signedOut:
                print("user signed out")
            case .signedIn:
                print("user is signed in.")
                print(AWSMobileClient.default().identityId as Any)
                self.awsIoTInit()
            case .signedOutUserPoolsTokenInvalid:
                print("need to login again.")
            case .signedOutFederatedTokensInvalid:
                print("user logged in via federation, but currently needs new tokens")
            default:
                print("unsupported")
            }
        }
func awsIoTInit() {
        let credentialsProvider = AWSCognitoCredentialsProvider.init(regionType:AWSIDRegion, identityPoolId: identityPoolId)
        // Init IOT
        let iotEndPoint = AWSEndpoint(urlString: IOT_ENDPOINT)
        let configuration = AWSServiceConfiguration(region:AWSIDRegion, credentialsProvider:credentialsProvider)
        let iotDataConfiguration = AWSServiceConfiguration(region: AWSUserRegion,
                                                           endpoint: iotEndPoint,
                                                           credentialsProvider: AWSMobileClient.default())
        AWSServiceManager.default().defaultServiceConfiguration = configuration
        iotManager = AWSIoTManager.default()
        iot = AWSIoT.default()
        AWSIoTDataManager.register(with: iotDataConfiguration!, forKey: ASWIoTDataManager)
        iotDataManager = AWSIoTDataManager(forKey: ASWIoTDataManager)
        print(AWSMobileClient.default().identityId as Any)
    }

After a successful login, the addUserStateListener method retrieves that identityId is nil.

After delaying 4S, identityId can be successfully obtained, which I think is not normal:

AWSMobileClient.default().addUserStateListener(self) { (userState, info) in
            switch (userState) {
            case .guest:
                print("user is in guest mode.")
            case .signedOut:
                print("user signed out")
            case .signedIn:
                print("user is signed in.")
                sleep(4)
                print(AWSMobileClient.default().identityId as Any)
                self.awsIoTInit()
            case .signedOutUserPoolsTokenInvalid:
                print("need to login again.")
            case .signedOutFederatedTokensInvalid:
                print("user logged in via federation, but currently needs new tokens")
            default:
                print("unsupported")
            }
        }

Environment(please complete the following information):

SDK Version: 2.12.0
Dependency Manager: Cocoapods
Swift Version : 4.0

Device Information (please complete the following information):

Device: iPhone Xs Max
iOS Version: iOS 13.1.2

All 6 comments

I had the same problem
AWSMobileClient.default().identityId value is nil

AWSMobileClient.default().addUserStateListener(self) { (userState, info) in
            switch (userState) {
            case .guest:
                print("user is in guest mode.")
            case .signedOut:
                print("user signed out")
            case .signedIn:
                print("user is signed in.")
                print(AWSMobileClient.default().identityId as Any)
                self.awsIoTInit()
            case .signedOutUserPoolsTokenInvalid:
                print("need to login again.")
            case .signedOutFederatedTokensInvalid:
                print("user logged in via federation, but currently needs new tokens")
            default:
                print("unsupported")
            }
        }
func awsIoTInit() {
        let credentialsProvider = AWSCognitoCredentialsProvider.init(regionType:AWSIDRegion, identityPoolId: identityPoolId)
        // Init IOT
        let iotEndPoint = AWSEndpoint(urlString: IOT_ENDPOINT)
        let configuration = AWSServiceConfiguration(region:AWSIDRegion, credentialsProvider:credentialsProvider)
        let iotDataConfiguration = AWSServiceConfiguration(region: AWSUserRegion,
                                                           endpoint: iotEndPoint,
                                                           credentialsProvider: AWSMobileClient.default())
        AWSServiceManager.default().defaultServiceConfiguration = configuration
        iotManager = AWSIoTManager.default()
        iot = AWSIoT.default()
        AWSIoTDataManager.register(with: iotDataConfiguration!, forKey: ASWIoTDataManager)
        iotDataManager = AWSIoTDataManager(forKey: ASWIoTDataManager)
        print(AWSMobileClient.default().identityId as Any)
    }

After a successful login, the addUserStateListener method retrieves that identityId is nil.

After delaying 4S, identityId can be successfully obtained, which I think is not normal:

AWSMobileClient.default().addUserStateListener(self) { (userState, info) in
            switch (userState) {
            case .guest:
                print("user is in guest mode.")
            case .signedOut:
                print("user signed out")
            case .signedIn:
                print("user is signed in.")
                sleep(4)
                print(AWSMobileClient.default().identityId as Any)
                self.awsIoTInit()
            case .signedOutUserPoolsTokenInvalid:
                print("need to login again.")
            case .signedOutFederatedTokensInvalid:
                print("user logged in via federation, but currently needs new tokens")
            default:
                print("unsupported")
            }
        }

Environment(please complete the following information):

SDK Version: 2.12.0
Dependency Manager: Cocoapods
Swift Version : 4.0

Device Information (please complete the following information):

Device: iPhone Xs Max
iOS Version: iOS 13.1.2

Hi,

AWSMobileClient.default().identityId returns the id stored in the keychain. If the identityId is not fetched yet, it will return nil. Use getIdentityId() method to force a server fetch when identityId is not available.

@karasahinemre From the error it looks like you do not have identity pool information in your awsconfiguration.json.

@karasahinemre I think I found a bug in the SDK/documentation. Instead of initializing the mobile client like this:

let mobileClient = AWSMobileClient(configuration: configuration)
mobileClient.initialize { (userState, error) in
           ...
}

Can you try this:

_ = AWSMobileClient(configuration: configuration)
AWSMobileClient.default().initialize { (userState, error) in
~~ ...~~
}

If you are initializing the mobile client using the above step, please use the in-memory object of AWSMobileClient to make other api calls instead of the singleton AWSMobileClient.default(). For example:

func getTokens() {
        mobileClient.getTokens { (tokens, error) in
           ...
        }
}

Let us know if this fixes the issue.

I also have the same bug, the identityID is nil right after a successful sign in. But it has a value a little delay after.

func logInAndCreateTable(email: String, password: String, name: String) {
       AWSMobileClient.default().signIn(username: email, password: password) { (signInResult, error) in
           if let error = error  {
               print("\(error.localizedDescription)")
           } else if let signInResult = signInResult {
               switch (signInResult.signInState) {
               case .signedIn:

                AWSMobileClient.default().getIdentityId().continueOnSuccessWith(block: {_ in
                    self.createParent(name: name,id: AWSMobileClient.default().identityId!, email: email)
                })

               case .smsMFA:
                   print("SMS message sent to \(signInResult.codeDetails!.destination!)")
               default:
                   print("Sign In needs info which is not yet supported.")
               }
           }
       }
   }

Do you have a solution for the bug? A little delay would solve it, but is not a complete solution for it in my opinion.

Ohh sorry this did the trick as you wrote @royjit

                AWSMobileClient.default().getIdentityId().continueOnSuccessWith(block: {_ in
                    self.createParent(name: name,id: AWSMobileClient.default().identityId!, email: email)
                })

@Nicolaidam glad it worked. I am closing this issue, feel free to open a new one if you face any other issue with the SDK.

Was this page helpful?
0 / 5 - 0 ratings