I'm trying to use the AWS SDK to create an endpoint on an application so that I can send push notifications. The push notifications go through when I manually enter the details on the AWS console but I'm trying to register the device from inside the app so that new users can be signed up.
Following the steps on http://docs.aws.amazon.com/mobile/sdkforios/developerguide/setup.html I have created the credentials for the app in the AppDelegate and use these credentials in another class.
The code I'm using to try and access the AWS SNS is :
func subscribeEndpoint(json: JSON)
{
let sns = AWSSNS.defaultSNS()
let request = AWSSNSCreatePlatformEndpointInput()
let user_id = json["id"].string!
request.token = "XXXXX"
request.customUserData = user_id
print("token : \(token) user : \(user_id)")
request.platformApplicationArn = "XXXX"
sns.createPlatformEndpoint(request).continueWithBlock({ (task: AWSTask!) -> AnyObject! in
if task.error != nil {
print("Error dis: \(task.error!)")
} else {
let createEndpointResponse = task.result as! AWSSNSCreateEndpointResponse
print("endpointArn: \(createEndpointResponse.endpointArn)")
}
return nil
})
}
I have tested using the device token generated by the device when registering for notifications (this value works when inputting on the AWS SNS console). The user_id has also been tested and isn't null.
The error I keep getting is
Error dis: Error Domain=com.amazonaws.AWSSNSErrorDomain Code=0 "(null)"
Not really sure what the cause of the problem is but if anyone could help me it would be greatly appreciated. Thanks
This is most likely an authorization error. Are you setting the default service configuration correctly?
When you use AWSSNS.defaultSNS() it loads the configuration from the default configuration object. The credential provider used for the default configuration should assume a role which has permissions to call createPlatformEndpoint from the client.
You can verify it from the IAM console if the role that is assumed has enough permissions.
Thanks,
Rohan
Related
I've been working with the Amplify SDK to get federatedSignIn working with my iOS app with "Sign in with Apple" and Cognito to eventually make calls to API Gateway / Lambda functions.
TL;DR : My access token does not appear to be "automatically included in outbound requests" to my API as per the last paragraph of this section of the docs : Cognito User pool authorization
I have successfully authenticated using the tutorial found here Authentication Getting Started and other various Youtube videos on the Amazon Web Services channel.
Upon successful sign in through Apple I'm given an ASAuthorizationAppleIDCredential object. This contains the user field (token) which I pass to the Amplify.Auth class using the following Swift code :
func signIn (with userId: String)
{
guard
let plugin = try? Amplify.Auth.getPlugin(for: AWSCognitoAuthPlugin().key),
let authPlugin = plugin as? AWSCognitoAuthPlugin,
case .awsMobileClient (let client) = authPlugin.getEscapeHatch()
else
{
return
}
client.federatedSignIn(providerName: AuthProvider.signInWithApple.rawValue, token: userId) { (state, error) in
if let unwrappedError = error
{
print (unwrappedError)
}
else if let unwrappedState = state
{
print ("Successful federated sign in:", unwrappedState)
}
}
}
All appears to be successful and to double check I use the following bit of code to ensure I'm authorized :
func getCredentialsState (for userId:String)
{
let provider = ASAuthorizationAppleIDProvider()
provider.getCredentialState(forUserID: userId) { (credentialsState, error) in
if let unwrappedError = error
{
print (unwrappedError)
}
switch credentialsState
{
case .authorized:
print ("User Authorized")
case .notFound, .revoked:
print ("User Unauthenticated")
case .transferred:
print ("User Needs Transfer")
#unknown default:
print ("User Handle new use cases")
}
}
}
In the console I see "User Authorized" so everything appears to be working well.
However when I then go to make a call to Amplify.API.post I get the following error:
[Amplify] AWSMobileClient Event listener - signedOutFederatedTokensInvalid
Failed APIError: Failed to retrieve authorization token.
Caused by:
AuthError: Session expired could not fetch cognito tokens
Recovery suggestion: Invoke Auth.signIn to re-authenticate the user
My function for doing the POST is as follows :
func postTest ()
{
let message = #"{'message": "my Test"}"#
let request = RESTRequest (path: "/test", body: message.data(using: .utf8))
Amplify.API.post (request:request)
{
result in switch result
{
case .success(let data):
let str = String (decoding: data, as: UTF8.self)
print ("Success \(str)")
case .failure(let apiError):
print ("Failed", apiError)
}
}
}`
I then went into the API Gateway UI and changed the generated Method Request on my resource from AWS IAM to my Cognito User Pool Authorizer thinking this was the issue. I also changed the awsAPIPlugin authorizationType to "AMAZON_COGNITO_USER_POOLS" in my amplifyconfiguration.json file. This unfortunately did not have any affect.
I've seen posts such as this issue User is not created in Cognito User pool for users logging in with Google federated login #1937 where people discuss the problem of having to to use a web ui to bring up the social sign in. I understand that Apple will reject your app sometimes for this. Therefore this is not a solution.
I then found this post which seems to resolve the issue however this appears to use the old version of the SDK? Get JWT Token using federatedSignIn #1276
I'm not great with Swift (I'm still an Objective C expert, but am slowly learning Swift) so I'm uncertain which path to go here and whether this is actually a solution? It does seem to be quite more complicated than the function I have that does my POST? The RESTRequest does seem to be a simple and easy solution but I'm uncertain how to pass it the Authorization token (or even how to get the token if it is needed here).
However, everything I've read about the SDK is that the authorization should be handled automatically in the background according the docs in my first link above. Specifically pointed out, again, here : Cognito User pool authorization. The last paragraph here states 👍
With this configuration, your access token will automatically be included in outbound requests to your API, as an Authorization header.
Therefore, what am I missing here as this does not appear to automatically include my access token to my outbound requests to my API?
I'm trying to refresh my auth token in Firebase using swift as follows
let currentUser = Auth.auth().currentUser
currentUser?.getIDTokenForcingRefresh(true) { idToken, error in
if error != nil {
return;
}
self.userDataManager.fetchUser()
}
It's hitting the error return statement with,
message = "Requests to this API securetoken.googleapis.com method google.identity.securetoken.v1.SecureToken.GrantToken are blocked.";
status = "PERMISSION_DENIED";
I search around the docs, But couldn't find a proper solution for this. Please help with this.
I had the same error but with the Web APIs. Solved it by
Going to https://console.developers.google.com/apis/credentials,
Clicking on the API key
Enabling the "Token Service API", along with "Identity Toolkit API"
I'm having a problem integrating Firebase with Microsoft Auth in my iOS App.
The login page has been launched and I can sign in by Office365 account but login auth can not be finished because of the below Error :
"AADSTS50011: The reply url specified in the request does not match the reply urls configured for the application:[app-id]"
I did check the setting in Firebase and below are the settings I add in the app of Azure Active Directory :
Web redirect URL : "*.firebaseapp.com/__/auth/handler"
Supported account types : "Accounts in any organizational directory (Any Azure AD directory Multitenant)"
Here are the swift code I implement :
provider = OAuthProvider(providerID: "microsoft.com")
provider?.customParameters = ["prompt": "consent",
"login_hint": "Login Hint"]
provider?.scopes = ["mail.read", "calendars.read"]
provider?.getCredentialWith(_: nil){ (credential, error) in
if let credential = credential {
Auth.auth().signIn(with: credential) { (authResult, error) in
if let error = error {
print(error.localizedDescription)
}
}
}
}
Does anyone know how to solve the problem or have the same problem?
When registering apps with these providers, be sure to register the
*.firebaseapp.com domain for your project as the redirect domain for your app.
Have you replaced * with your projectName? You can find your Authorized Domain under Authorized Domains in firebase console. The redirect uri should be something like
https://yourFirebaseApp.firebaseapp.com/__/auth/handler
I'm trying to get working Facebook authentification in my app.
I'm following instructions here : https://firebase.google.com/docs/auth/ios/facebook-login
When I clicked on the Facebook login button, everything is working fine : the user is logged. In the facebook login delegate method, it is ok :
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!)
In this method, I have to create a Firebase token to authenticate finally with Firebase (step 5). This is what I do :
let credential = FacebookAuthProvider.credential(withAccessToken:
FBSDKAccessToken.current().tokenString)
Auth.auth().signIn(with: credential) { (user, error) in
if let error = error {
print(error.localizedDescription)
self.errorServer()
} else {
FitUtils.setFitUser(user: user)
}
}
The problem : My credential variable is not nil, everything is working, but when i'm calling Auth.auth().signIn(...), the method throwns the error variable, and user is nil.
I don't have many information about the error :
An internal error has occurred, print and inspect the error details
for more information.
And
error NSError domain: "FIRAuthErrorDomain" - code: 17999 0x0000604000640630
I suspect an error about the Facebook API key or something like that in the Firebase console, but I already checked everything is fine.
Any idea ?
EDIT
I found an explicit description of the error :
UserInfo={FIRAuthErrorUserInfoDeserializedResponseKey={
code = 400;
errors = (
{
domain = global;
message = "Unsuccessful debug_token response from Facebook: {\"error\":{\"message\":\"(#100) You must provide an app access token or a user access token that is an owner or developer of the app\",\"type\":\"OAuthException\",\"code\":100,\"fbtrace_id\":\"GkGVPPBP7vo\"}}";
reason = invalid;
}
);
message = "Unsuccessful debug_token response from Facebook: {\"error\":{\"message\":\"(#100) You must provide an app access token or a user access token that is an owner or developer of the app\",\"type\":\"OAuthException\",\"code\":100,\"fbtrace_id\":\"GkGVPPBP7vo\"}}";
}}}}
(lldb)
Finally found an answer thanks to this post :
https://github.com/firebase/FirebaseUI-iOS/issues/83#issuecomment-232523935
I have to disable the option "Is App Secret embedded in the client?" in the Facebook console :
Hope this helps.
On the Facebook Developer site, navigate to:
Settings > Advanced > Security > Require App Secret
Set to YES.
Fixed it for me.
The following worked for me:
Go to android/app/src/main/res/values/strings.xml. Make sure you have the following line in your <resources>:
<string name="facebook_app_id">FACEBOOK*APP*ID</string>
where FACEBOOK*APP*ID is the your app ID from developers.facebook.com/apps
In my case, there was set wrong App secret in Firebase 🤷🏻♂️
Go to the Firebase console and choose the project.
Under Project shortcuts choose Authentication.
Select Sign-in method tab.
In Sign-in providers click on Facebook to edit.
Set the correct App secret from your Facebook app.
I'm using AWS SDK 2.5 and Swift 3. Having gotten S3 to work in Android, I'm transitioning to iOS and Swift.
After following the solution in another StackOverflow question Checking metadata of Amazon S3, I receive an OSStatus error [-34018] Security error has occurred.
Here's the code snippet based on that solution.
let request = AWSS3HeadObjectRequest()
request!.bucket = bucketName
request!.key = key
let s3 = AWSS3.default()
s3.headObject(request!) {
(output1 : AWSS3HeadObjectOutput?, error : Error?) -> Void in
if error == nil {
print("Error: could not find file \(error)")
} else {
print (output1?.lastModified! ?? "")
}
}
I have a valid Cognito pool ID, bucket and key. I'm not sure what the issue is. Any suggestions would be greatly appreciated.
You need to enable keychain capability in your XCode project. Apple changed the way how keychain is accessed on iOS10. for more information please see https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/AddingCapabilities/AddingCapabilities.html