swift3facebook-ios-sdkaws-lambdaamazon-cognitoaws-sdk-ios

AWS Cognito integration swift3 Refresh provides ResourceNotFoundException


Following the answer here: https://github.com/aws/aws-sdk-ios/issues/357 At the very bottom there is a mini guide on getting swift and cognito working.

I've made a AWSCustomIdentityProvider as such:

import Foundation
import AWSCognitoIdentityProvider
import AWSCognito

class AWSCustomIdentityProvider: NSObject, AWSIdentityProviderManager
{

private var dict = NSDictionary()

func addToken(value:NSString)
{
    dict = ["graph.facebook.com":value]
}

public func logins() -> AWSTask<NSDictionary>
{
    return AWSTask(result: dict)
}
}

And I have a login method from facebook:

public func loginButtonDidCompleteLogin(_ loginButton: FacebookLogin.LoginButton, result: FacebookLogin.LoginResult){

    switch result {
    case .failed(let error):
        print("FACEBOOK LOGIN FAILED: \(error)")
    case .cancelled:
        print("User cancelled login.")
    case .success(_, _, let accessToken):


        let customIdentity = AWSCustomIdentityProvider()
        let token = accessToken.authenticationToken
        customIdentity.addToken(value: token as NSString)

        let credentialsProvider = AWSCognitoCredentialsProvider(regionType: REGIONTYPE, identityPoolId: "XXXXXXXXXXXXXXXXXXXXXXX", identityProviderManager:customIdentity)

        credentialsProvider.clearKeychain()
        credentialsProvider.clearCredentials()

        let serviceConfiguration = AWSServiceConfiguration(region: REDIONTYPE, credentialsProvider: credentialsProvider)
        AWSServiceManager.default().defaultServiceConfiguration = serviceConfiguration;

        credentialsProvider.getIdentityId().continue( { (task: AWSTask!) -> AnyObject! in
            if (task.error != nil) {
                print("Error: " + (task.error?.localizedDescription)!)// gets called
            }
            else {
                print(task.result)//identityid
            }
            return nil
        })
    }
}

However I get the error:

Error Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=8 "(null)" UserInfo={__type=NotAuthorizedException, message=Logins don't match. Please include at least one valid login for this identity or identity pool.}

Please let me know if you have any idea on how to resolve my issue. I've tried also following the docs and setting the logins directly "credentialsProvider.logins = {"graph.facebook.com": mytoken}

and that produces a different exception upon invoking a lambda method but DOES retrieve the identityID properly. However doing it according to the docs makes a warning that the method I'm using is deprecated.

The error I get:

UserInfo={NSLocalizedDescription=serialized object is neither a valid json Object nor NSData object: }

However that only happens sometimes. If I retry then i can potentially get the identity id but upon invoking a lambda method, I get the same error. I'm assuming it is a cognito issue.

UPDATE

If I use AWSCognitoLoginProviderKey.facebook.rawValue instead of graph.facebook.com in the first part, then it gives me the cognito ID and then I invoke the lambda method. I'll include the lambda method just incase that's the part I'm getting wrong but I'm decently sure that it's cognito that is preventing me from calling the lambda method:

import AWSLambda
import Foundation
struct AWSHelper{
let lambda = AWSLambda.default()
let APPLICATION_NAME = "MYAPPLICATION"
init(){

}

func getFunctionName(funcName: String) -> String{
    return "\(funcName)_\(APPLICATION_NAME)"
}

func login(facebookID: String, cognitoID:String, callback:@escaping (Bool) -> Void){
    let req = AWSLambdaInvocationRequest();
    req?.invocationType = AWSLambdaInvocationType.requestResponse
    req?.payload = ["cognitoID" : cognitoID, "facebookID" : facebookID]
    req?.functionName = getFunctionName(funcName: "MYFUNCNAME")

    lambda.invoke(req!) { (response: AWSLambdaInvocationResponse?,error: Error?) in
        print(error)
        let payload = response?.payload
        print(payload)
        callback(true)
    }

}
}

Update 2

I have found out that calling a refresh method like this:

credentialsProvider.credentials().continue({ (task: AWSTask!) -> Any? in
            print(task.result)
        })

Causes an error like this:

AWSiOSSDK v2.4.10 [Error] AWSCredentialsProvider.m line:577 | __44-[AWSCognitoCredentialsProvider credentials]_block_invoke.352 | Unable to refresh. Error is [Error Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=10 "(null)" UserInfo={__type=ResourceNotFoundException, message=Identity 'us-east-1:0db18266-1baa-4c59-9110-f9041dc92ead' not found.}]

I believe the big string that looks like an identitypoolID is actually the identityID for the given user that I have, so cognito has distributed an ID but is not able to query it?


Solution

  • Few things that made it work I think.

    I made the correct move by making my own identityprovidermanager and I think the main thing that was blocking me from executing a lambda method was actually the fact that I was using AWSLambda instead of AWSLambdaInvoker. After I switched it started making errors that made sense.