This used to work before I updated to Swift 3, but I don't think this is really coming from this. Here is my problem:
I would like to create a Dropbox sharable link from my Swift app as follow:
client.sharing.createSharedLinkWithSettings(path: myPath).response { response, error in
if let link = response {
// share the link
} else {
print(error)
}
}
but this is the error I get:
[request-id 431f08cc7e243504a437cec661247dd2] API route error - {
".tag" = "email_not_verified";
}
and I don't really understand how should I verify the email.
I can log in with dropbox, I authorised the app, I can write files and folders, etc.
I didn't received a verification email on my device. I tried with a different account and received this verification email from dropbox.
Related
I have an app on TestFlight that I'm trying to setup passwordless signin using emailid from FireBase.
I've done the following:
Enabled Passwordless sign in on Firebase console
Created a Dynamic link on Firebase.
httpsdotslashslash<custom domain>/login/?link=https://<custom domain>/login&isi=<app id from itunes connect. Looks like this: 167*******>&ibi=<bundleid>
Confirmed that https://<custom domain>/apple-app-site-association returns correctly. Note that I'm using Firebase hosting to host this site. And have confirmed that https://<firebase-projectid>.firebase.app/apple-app-site-association also returns the above. i.e. custom domain is correctly resolving to this firebase hosting url.
In Info, Added a url type with identifier 'appLink' and 'url scheme'
Ensured that my GoogleService-Info is current
Enabled Associated Domains in 'Signing and Capabilities' in my project Target under 'All' (not just Debug or Release)
Added applinks:<customdomain> and activitycontinuation:<customdomain>
In my 'SceneDelegate', I'm handling the dynamic link with
private func handleIncomingDynamicLink(_ incomingURL: URL) {
DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { dynamicLink, error in
guard error == nil else {
return print("ⓧ Error in \(#function): \(error!.localizedDescription)")
}
guard let link = dynamicLink?.url?.absoluteString else { return }
if Auth.auth().isSignIn(withEmailLink: link) {
// Save the link as it will be used in the next step to complete login
UserDefaults.standard.set(link, forKey: "Link")
}
}
}
In my viewcontroller, have copied the code from Firebase's quickstart PasswordlessViewController.swift as is.
Observed behavior:
The email link is being sent. Here's what it looks like though. Not sure if this is right.
httpsdotslashslash<custom domain>/?link=https://<firebase-projectid>.firebaseapp.com/__/auth/action?apiKey=<web api key>&mode=signIn&oobCode=25CRdL7n3qXNatDT2nEypR9UWy17E_G0ChlmqrkpznsAAAGGLYK3jQ&continueUrl=https://<custom domain>/login&lang=en&ibi=<bundleid>&ifl=https://<firebase-projectid>.firebaseapp.com/__/auth/action?apiKey=<web api key>&mode=signIn&oobCode=25CRdL7n3qXNatDT2nEypR9UWy17E_G0ChlmqrkpznsAAAGGLYK3jQ&continueUrl=https://<custom domain>/login&lang=en
Clicking on this url in my email correctly opens my app. handleIncomingDynamicLink() is also called correctly. But it throws the error ⓧ Error in handleIncomingDynamicLink(_:): The operation couldn’t be completed. Universal link URL could not be parsed by Dynamic Links.
Have tried a bunch of things.
But, unable to proceed beyond this stage. Not sure what is wrong with my link. What is it supposed to look like when behaving correctly? Should i be doing something with the oobCode? Why are there two redirections?
Happy to assist with any other information. Thank you!
I was able to solve it by adding all my url prefixes to info.plist.
<key>FirebaseDynamicLinksCustomDomains</key>
<array>
<string>https://<custom domain>/login</string>
<string>https://<custom domain>/</string>
</array>
More details at https://firebase.google.com/docs/dynamic-links/custom-domains#console
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 try to integrate google drive into my app to list mp3, m4a music files. Now I have made Google sign working, means I could signIn and signOut google account.
But when I follow google's api doc to this step Make an API call with fresh tokens, I got above error on line let authorizer = authentication.fetcherAuthorizer(). This function fetcherAuthorizer is not found.
I think maybe this doc is not up to date with latest google sdk. So I did a few search on Google...then it appears there is really rare stuff about this topic. What I found is all used this same code authentication.fetcherAuthorizer().
Thus, guys. Is there any update about this code?
user.authentication.do { authentication, error in
guard error == nil else { return }
guard let authentication = authentication else { return }
// Get the access token to attach it to a REST or gRPC request.
let accessToken = authentication.accessToken
// Or, get an object that conforms to GTMFetcherAuthorizationProtocol for
// use with GTMAppAuth and the Google APIs client library.
let authorizer = authentication.fetcherAuthorizer()
}
Today, I find the answer in this thread googlesignin-ios
The reason is Swift cannot find the fetcherAuthorizer from Objective-C library, we must manually import it import GTMSessionFetcher.
In my iOS app I'm trying to use the Facebook Swift SDK so that a user can post a URL to a specific Facebook page that they manage.
I've managed to get the following code working - but it only shares the post to my home timeline:
let content = LinkShareContent(url: URL(string: urlString)!)
let sharer = GraphSharer(content: content)
sharer.failsOnInvalidData = true
sharer.completion = {
(result) in
print(result)
}
do {
try sharer.share()
}
catch (let error) {
print(error.localizedDescription)
}
I believe that I need to use the graphNode property to specify the destination page and that the correct format is as follows:
sharer.graphNode = "/\(pageId)"
However, when I set this property before posting, I am getting an error:
failed(Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL"
I've tried a dozen different formats to specify the node but they all return the same error and I can't find any working examples.
I managed to resolved this issue. It turns out that the graphNode path above is correct but I was looking in the wrong place due to the error message I was getting. Instead I just needed to specify the accessToken parameter.
graphSharer.accesstoken = myPageAccessToken
Note: The access token is not the user's current access token, but an access token you can retrieve when calling the /me/accounts API.
var graphPath = "/me/accounts"
I also then had an issue posting to the page because I had only requested the publish_actions permission. From the documentation, this appears to be suitable but it only worked where I requested further permissions as follows:
loginManager.logIn(withPublishPermissions: ["publish_actions",
"manage_pages", "publish_pages"], ...
Hopefully this will be of use to someone in future. :-)
I want to use the YouTube Data API to get the links to thumbnails for a specific YouTube video in my iOS app. I went to Google Developers Console and created a new project.
For that project I then went to "APIs" and removed the default APIs it enables for me and added the YouTube Data API. I then went to credentials, created a Public Key (as I don't need the user to log in or anything, just getting the thumbnail URLs) as iOS, which gave me an API key. I added the Bundle Identifier for my project under Allowed Applications.
Now in my app I tried the following code:
let test = NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: "https://www.googleapis.com/youtube/v3/videos?id=7lCDEYXw3mM&key=*MYKEYHERE*&part=snippet,contentDetails,statistics,status")!, completionHandler: { (data, response, error) -> Void in
let json = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil)
println("JSON: \(json)")
})
But it prints out the error:
JSON: Optional({
error = {
code = 403;
errors = (
{
domain = usageLimits;
message = "Access Not Configured. Please use Google Developers Console to activate the API for your project.";
reason = accessNotConfigured;
}
);
message = "Access Not Configured. Please use Google Developers Console to activate the API for your project.";
};
})
What exactly am I doing wrong?
There is a known problem about Bundle id in the console. If you can just remove that restriction, it should just work fine.
You can track the original issue from here: https://code.google.com/p/gdata-issues/issues/detail?id=5770
Here's what you need, YouTube has a service API via web to consult this types of things. I'm using this URL to consult all videos from a user (getting every videos: URL, Thumbnail, views, duration, etc). I'm sure you'll find thumbnails for a particular video. Its a JSON response so you'll have to take a good look to the structure but can't get simpler than this.
http://gdata.youtube.com/feeds/api/users/USER_NAME/uploads?v=2&alt=json&#&start-index=1&max-results=10