I'm trying to get basic details of a user signing into my app with their Twitter account. I am able to sign them in but not too sure where to go from here.
I'm pretty sure I need to use this get request but am unsure how to structure the request. Am also a little lost which token I include.
I haven't had much experience with the REST API as you could tell. I have Postman set up so if someone could point me in the right direction about accessing the data I could take it from there.
Thanks
#IBAction func twitterSignupPress() {
provider.getCredentialWith(nil) { credential, error in
if error != nil {
print("Error attempting to sign up using Twitter: \(error!)")
} else {
Auth.auth().signIn(with: credential!) { authResult, error in
if error != nil {
print("Error with Twitter signin")
} else {
print("Successful signin using Twitter")
let oAuthCredential = authResult?.credential as! OAuthCredential
print(oAuthCredential.accessToken!) // Prints token
print(oAuthCredential.idToken) // Prints nil
}
}
}
}
}
Was as simple as adding authResult?.additionalUserInfo?.profile
Related
I incorporated Firebase's email verification for my iOS mobile app and am trying to resolve the following issues:
The length of the redirect url appears extremely long. It looks like it repeats itself.
https://app.page.link?link=https://app.firebaseapp.com//auth/action?apiKey%3XXX%26mode%3DverifyEmail%26oobCode%3XXX%26continueUrl%3Dhttps://www.app.com/?verifyemail%253Demail#gmail.com%26lang%3Den&ibi=com.app.app&ifl=https://app.firebaseapp.com//auth/action?apiKey%3XXX%26mode%3DverifyEmail%26oobCode%3XXX%26continueUrl%3Dhttps://www.app.com/?verifyemail%253Demail#gmail.com%26lang%3Den
When I set handleCodeInApp equal to true, and am redirected back to the app when I click on the redirect url, the user's email is not verified. Whereas when I set it to false and go through Firebase's provided web widget, it does get verified. Wasn't able to find documentation that outlined handling the former in swift...
Any thoughts are appreciated.
func sendActivationEmail(_ user: User) {
let actionCodeSettings = ActionCodeSettings.init()
let redirectUrl = String(format: "https://www.app.com/?verifyemail=%#", user.email!)
actionCodeSettings.handleCodeInApp = true
actionCodeSettings.url = URL(string: redirectUrl)
actionCodeSettings.setIOSBundleID("com.app.app")
Auth.auth().currentUser?.sendEmailVerification(with: actionCodeSettings) { error in
guard error == nil else {
AlertController.showAlert(self, title: "Send Error", message: error!.localizedDescription)
return
}
}
}
Make sure you're verifying the oobCode that is part of the callback URL.
Auth.auth().applyActionCode(oobCode!, completion: { (err) in
if err == nil {
// reload the current user
}
})
Once you have done that, try reloading the the user's profile from the server after verifying the email.
Auth.auth().currentUser?.reload(completion: {
(error) in
if(Auth.auth().currentUser?.isEmailVerified)! {
print("email verified")
} else {
print("email NOT verified")
}
})
I'm trying to unlink email/password authentication from a user in Swift on iOS. I've read the documentation and managed to link and unlink Facebook authentication without a problem. However, after linking email/password credentials successfully, the providerData object is nil. The providerID is "Firebase" but when I pass that to the unlink code the following error is thrown:
Error Domain=FIRAuthErrorDomain Code=17016 "User was not linked to an account with the given provider." UserInfo={NSLocalizedDescription=User was not linked to an account with the given provider., error_name=ERROR_NO_SUCH_PROVIDER}
The unlink code I'm using is:
let providerId = (FIRAuth.auth()?.currentUser?.providerID)!
print("Trying to unlink:",providerId) // providerId = "Firebase"
FIRAuth.auth()?.currentUser?.unlinkFromProvider(providerId) { user, error in
if let error = error {
print("Unlink error:", error)
} else {
// Provider unlinked from account successfully
print("Unlinked...user.uid:", user!.uid, "Anonymous?:", user!.anonymous)
}
}
Reading the docs and having got it working for Facebook, I expected the providerData array to be populated with something after email authentication. So is my linking code wrong (it doesn't throw an error and appears to work fine)?
My linking code:
let credential = FIREmailPasswordAuthProvider.credentialWithEmail(email, password: password)
FIRAuth.auth()?.currentUser!.linkWithCredential(credential) { (user, error) in
if user != nil && error == nil {
// Success
self.success?(user: user!)
dispatch_async(dispatch_get_main_queue(), {
self.dismissViewControllerAnimated(true, completion: nil)
if type == "new" {
print("New user logged in...")
}
if type == "existing" {
print("Existing user logged in...")
}
})
} else {
print("Login error:",error)
self.showOKAlertWithTitle("Login Error", message: error!.localizedDescription)
}
}
Any pointers of how I can modify my approach would be great.
To get the profile information retrieved from the sign-in providers linked to a user, use the providerData property.
if let user = FIRAuth.auth()?.currentUser {
for profile in user.providerData {
// Id of the provider (ex: facebook.com)
let providerID = profile.providerID
}
} else {
// No user is signed in.
}
Calling FIRAuth.auth()?.currentUser?.providerID will result to "firebase".
I have an iOS app that uses Firebase as a backend for authentication.
Once a user logs in and then closes the app, I don't want the user to have to re-enter their email and password. My approach is to save the access token after a successful login to the Keychain, and then when the user comes back to the app, use the token from the keychain to signin.
I've tried using the method FIRAuth.auth()?.signInWithCustomToken(customToken) { (user, error) in but that's not quite right as that's for when using custom tokens, which is not what I'm doing.
Is there a way for me to do this?
// login with email / password
FIRAuth.auth()?.signInWithEmail(email, password: password, completion: { (firebaseUser, error) in
if error == nil {
FIRAuth.auth()!.currentUser!.getTokenWithCompletion({ (token, error) in
if error == nil {
// save token to keychain
} else {
print(error)
}
})
} else {
print(error)
}
})
// user comes back to app
do {
// get saved token from keychain
if let myToken = try keychain.get("token") {
FIRAuth.auth()?.signInWithCustomToken(myToken, completion: { (user: FIRUser?, error: NSError?) in
if error == nil {
// show post login screen
} else {
}
})
}
} catch {
// error getting token from keychain
}
}
I was approaching this problem in the wrong way. Saving a token is appropriate when using a 3rd party authentication provider, like Facebook, Google, etc and getting an OAuth token in return from one of those services.
In my case when logging in using email and password, a token is not required and instead the password can be securely saved in the Keychain and used later for login.
I have to implement a chat platform using firebase and swift.
I know how to create a user using emailid :
firebase.createUser(emailTextField, password: passwordTextField.text) { (error:NSError!) -> Void in
if (error != nil){
print(error.localizedDescription)
self.displayMessage(error)
} else{
print("New user created")
self.requestUsername()
}
}
But I am not taking any email id or other accounts. I want to create a custom user. For that they have mentioned to use the secure JWT Token and then use this :
let ref = Firebase(url: "https://<YOUR-FIREBASE-APP>.firebaseio.com/")
ref.authWithCustomToken(AUTH_TOKEN, withCompletionBlock: { error, authData in
if error != nil {
println("Login failed! \(error)")
} else {
println("Login succeeded! \(authData)")
}
})
But they have not mentioned how to generate secure JWT Token in swift.
Anyone know?
Here is the link i referred:
How to login in firebase
As you probably noticed, there is no helper library from Firebase for minting custom tokens on iOS. There is however a set of instructions on how to mint tokens here: https://www.firebase.com/docs/ios/guide/login/custom.html#section-tokens-without-helpers
Minting tokens in a client-app is in general a VERY bad idea, since it requires that you have your Firebase's secret in your app, where any user can find it.
I'm currently developing an iOS App that allows login via Facebook/Parse. The login flow goes like this:
login button is touched and Facebook login window opens;
user logs in and gives permission on Facebook;
app retrieves Facebook accessToken information;
app performs [PFFacebookUtils logInInBackGroundWithAccessToken:(accessToken) ^block{}] to make the Parse login authentication;
app goes to a view and tries to perform a query to fetch data associated with that user from Parse.
The problem is: after logInInBackgroundWithAccessToken is performed, [PFUser currentUser] returns nil, and I get a "Cannot do a comparison query for type: (null)" error.
Ok! Solved it!
After digging into the code a little further I realized that the
[PFFacebookUtils logInInBackgroundWithAccessToken:(accessToken) block:^(nullable__block){}];
callback wasn't being executed for unknown reasons.
To solve this I added a check into the view's -viewDidLoad method to see if there was a valid [FBSDKAccessToken currentAccessToken] but NOT a valid [PFUser currentUser], and if so I forced the method to be executed.
If you need a more thorough explanation, don't hesitate to leave your comment! Thanks!
if ((currentUser != nil)) {
if (PFFacebookUtils.isLinkedWithUser(currentUser!)) {
proccessCurrent(currentUser!)
} else {
PFFacebookUtils.linkUserInBackground(currentUser!, withReadPermissions: self.facebookReadPermissions, block: {(success, error) in
if (success) {
self.proccessCurrent(currentUser!)
} else {
self.presentWalkThroughViewController()
}
})
}
} else {
//var currentToken: FBSDKAccessToken = FBSDKAccessToken.currentAccessToken()
if (FBSDKAccessToken.currentAccessToken() == nil) {
self.presentWalkThroughViewController()
} else {
var currentToken: FBSDKAccessToken = FBSDKAccessToken.currentAccessToken()
PFFacebookUtils.logInInBackgroundWithAccessToken(currentToken, block: {(user, error) in
if (error == nil) {
user?.pinInBackgroundWithBlock({(success, error) in
if (success) {
self.proccessCurrent(user!)
} else {
self.presentWalkThroughViewController()
}
})
} else {
self.presentWalkThroughViewController()
}
})
}
}
The methods processCurrentUser, continue to process my program execution and presentWalkThroughViewController presents the login screens. Is this a safe way to handle skipping the login screen on facebook once a user is already logged in?