i am using phone number authenticator for verify my user. i have verify them using following code.
PhoneAuthProvider.provider().verifyPhoneNumber(mobileNo!, uiDelegate: nil) { (verificationID, error) in
if error != nil {
self.errorLabel.text = error?.localizedDescription
}else{
log.success("\(mobileNo!)")/
// add authentication code to the defaults
let defaults = UserDefaults.standard
defaults.set(verificationID, forKey: "authVID")
self.performSegue(withIdentifier: "sendCode", sender: Any?.self)
}
}
verify the code using following code
func verifyCode(){
let defaults = UserDefaults.standard
let credential: PhoneAuthCredential = PhoneAuthProvider.provider().credential(withVerificationID: defaults.string(forKey: "authVID")!, verificationCode: verficationCodeTextField.text!)
Auth.auth().signIn(with: credential) { (user, error) in
if error != nil {
self.errorLabel.text = error?.localizedDescription
self.errorLabel.alpha = 1
}else{
self.transitionToRegistration()
}
}
}
now i need to get the userid from the authentication ?
this can be done by using following code line.
guard let userID = Auth.auth().currentUser?.uid else { return }
Related
I'm using AWS Cognito for my app Sign In and Sign up. In my app first the user register with email and phone number. After that, I'm redirecting to Verification Screen(Here OTP is sending by Cognito) After Verifying the OTP user will create some stores and then enter into the Dashboard. In this flow, I want to get the User details Attribute from Cognito in Verification code success. I've implemented the getDetails() method to get the userAttributes in Verification code success but it is not calling. I need the userAttributes when the time of store creation. Any help appreciated.
Here is my code:
#IBAction func submitButtonAction(_ sender: GradientButton) {
let code = firstChar+secondChar+thirdChar+fourthChar+fifthChar+sixthChar
guard code.count == 6 else{
self.showAlert(message: ErrorMessages.kEnterValidOTP)
return
}
let currentUser = self.userPool?.getUser("xxxx#gmail.com")
currentUser?.confirmSignUp(code, forceAliasCreation: true).continueWith(block: { [weak self] (task) -> Any? in
guard let strongSelf = self else { return nil }
DispatchQueue.main.async {
if let error = task.error as NSError? {
if let message = error.userInfo["message"] as? String{
self?.showAlert(message: message, onOkAction: {
strongSelf.clearTextFieldData()
})
}else{
self?.showAlert(message: error.localizedDescription, onOkAction: {
strongSelf.clearTextFieldData()
})
}
}else{
print(task.result)
strongSelf.clearTextFieldData()
print(AWSUserDetails.shared.userPool.currentUser()?.username)
let user = AWSUserDetails.shared.userPool.currentUser()
//I've tried the above `user` and `currentUser`. But not working.
user?.getDetails().continueOnSuccessWith(block: { (task) -> Any? in
DispatchQueue.main.async {
if task.error == nil{
print(task.error)
}else{
print(task.result)
}
}
})
// strongSelf.performSegue(withIdentifier: SegueIdentifiers.createStoreSegue, sender: self)
}
}
return nil
})
}
Ok so in my code I get this error:'Value of type 'AuthDataResult' has no member 'uid''. Even after trying to use the authDataResult or the self.userUid = user.user.uid, I'm still getting the error. Here's my code if anyone wants to help me
#IBAction func SignIn (_ sender: AnyObject) {
if let email = emailField.text, let password = passwordField.text {
Auth.auth().signIn(withEmail: email, password: password, completion: { (user, error) in
if error == nil {
self.userUid = user.user.uid
KeychainWrapper.standard.set(self.userUid, forKey: "uid")
self.performSegue(withIdentifier: "toMessages", sender: nil)
} else {
self.performSegue(withIdentifier: "toSignUp", sender: nil)
}
})
}
}
Thanks if you can help me!
Inside if error == nil { do the following :
let user = Auth.auth().currentUser
if let user = user {
// The user's ID, unique to the Firebase project.
// Do NOT use this value to authenticate with your backend server,
// if you have one. Use getTokenWithCompletion:completion: instead.
let uid = user.uid
let email = user.email
}
You can find more information here:
https://firebase.google.com/docs/auth/ios/manage-users
When I log in with a facebook account in a view, I pass it a second view, in the second view I want a fetch query but in the view log I get permission denied and I dont see the info.
I have a normal firebase account, application test facebook.
this is the code view log in
#IBAction func InicioSesionFacebook(_ sender: Any)
{
esperaSesion.isHidden = false
esperaSesion.startAnimating()
let fbLoginManager = FBSDKLoginManager()
fbLoginManager.logIn(withReadPermissions: ["public_profile", "email"], from: self) { (result, error) in
if let error = error {
print("Failed to login: \(error.localizedDescription)")
self.esperaSesion.stopAnimating()
return
}
guard let accessToken = FBSDKAccessToken.current() else {
print("Failed to get access token")
self.esperaSesion.stopAnimating()
return
}
let credential = FacebookAuthProvider.credential(withAccessToken: accessToken.tokenString)
// Perform login by calling Firebase APIs
Auth.auth().signIn(with: credential, completion: { (user, error) in
if let error = error
{
self.esperaSesion.stopAnimating()
print("Login error: \(error.localizedDescription)")
let alertController = UIAlertController(title: "Login Error", message: error.localizedDescription, preferredStyle: .alert)
let okayAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(okayAction)
self.present(alertController, animated: true, completion: nil)
return
}
else
{
let fbloginresult : FBSDKLoginManagerLoginResult = result!
if (result?.isCancelled)!
{
return
}
else
{
// Present the main view
self.esperaSesion.stopAnimating()
if let viewController = self.storyboard?.instantiateViewController(withIdentifier: "NavigationMasterController")
{
UIApplication.shared.keyWindow?.rootViewController = viewController
self.dismiss(animated: true, completion: nil)
}
}
}
})
}
}
this is the code in the second view, a query
import FirebaseAuth
import FirebaseDatabase
import FBSDKLoginKit
var refDB: DatabaseReference!
override func viewDidLoad()
{
super.viewDidLoad()
refDB = Database.database().reference()
CerrarSesion.layer.cornerRadius = 8
imagenPerfil.layer.cornerRadius = imagenPerfil.frame.height/2
imagenPerfil.clipsToBounds = true
verDatos()
// Do any additional setup after loading the view.
}
func verDatos()
{
let userID = Auth.auth().currentUser?.uid
refDB.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
// Get user value
let value = snapshot.value as? NSDictionary
let nombre = value?["nombre"] as? String ?? ""
let apellido = value?["apellido"] as? String ?? ""
self.nombreUsuario.text = nombre
self.apellidoUsuario.text = apellido
// ...
}) { (error) in
print(error.localizedDescription)
}
}
and the button log out
#IBAction func CerrarSesion(_ sender: Any)
{
do
{
try Auth.auth().signOut()
self.view.window?.rootViewController?.dismiss(animated: true, completion: borrarUserDefaults)
}
catch let error as NSError
{
print (error.localizedDescription)
}
}
how is the correct form for log out when I logged in with facebook account?
You can check out my YouTube Tutorial on this exact topic !
https://www.youtube.com/watch?v=BfwNf-W-R4U
The version of the Facebook API that you are using is dated. The Login function should look something like this
let loginManager = LoginManager()
loginManager.logIn(readPermissions: [.publicProfile], viewController: self) {loginResult in
switch loginResult {
case .failed(let error):
print("error: \(error)")
case .cancelled:
print("User cancelled login.")
case .success(let grantedPermissions, let declinedPermissions, let accessToken):
print(grantedPermissions)
print(declinedPermissions)
fbAccessToken = accessToken
let credential = FacebookAuthProvider.credential(withAccessToken: (fbAccessToken?.authenticationToken)!)
Auth.auth().signIn(with: credential) { (user, error) in
if let error = error {
print(error)
return
}
currentUser = Auth.auth().currentUser
moveToHomeScreen()
print("Logged in!")
}
}
}
I think that you are getting a permissions error because the parameter name from the AccessToken changed and you are passing the wrong value. (Sorry I cant recall what the change was).
If you are following the Facebook API instructions on the facebook developer portal they are horrendously out of date iOS 9 I think.
Recently my facebook login hasn't been working. It doesn't save into my database but in Firebase authentication it shows someone signed in with facebook but the email is blank. It doesn't save any data to my database which it should. The email is returning nil. My google sign in works. I've checked all the connections and they all seem to be fine. (I could have missed something) anyone have any suggestions on what connections I should check? Not sure what to do...
More Info
I printed my graph request... not sure if this helps to debug
let loginManager: FBSDKLoginManager = FBSDKLoginManager()
loginManager.logIn(withReadPermissions: self.facebookPermissions, from: self, handler: { (result, error) in
if error != nil {
loginManager.logOut()
let message: String = "An error has occured. \(String(describing: error))"
let alertView = UIAlertController(title: "Alert", message: message, preferredStyle: UIAlertControllerStyle.alert)
alertView.addAction(UIAlertAction(title: "Ok ", style: UIAlertActionStyle.default, handler: nil))
self.present(alertView, animated: true, completion: nil)
} else if (result?.isCancelled)! {
// user cancelled login
loginManager.logOut()
} else {
let accessToken = FBSDKAccessToken.current()
guard let accessTokenString = accessToken?.tokenString else { return }
let credential = FacebookAuthProvider.credential(withAccessToken: accessTokenString)
Auth.auth().signIn(with: credential) { (user, error) in
if (error != nil) {
// handle error
print(error ?? "Error")
} else {
let ref = Database.database().reference()
// guard for user id
guard let uid = user?.uid else {
return
}
let usersReference = ref.child("user_profiles").child(uid)
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, email"])
graphRequest.start(completionHandler: { (connection, result, error) -> Void in
if error != nil {
// Process error
print("Error: \(String(describing: error))")
} else {
guard let data: [String:AnyObject] = result as? [String:AnyObject] else {
print("Can't pull data from JSON")
return
}
guard let userName: String = data["name"] as? String else {
print("Can't pull username from JSON")
return
}
guard let userID: String = data["id"] as? String else {
print("Can't pull ID from JSON")
return
}
let imgURLString = "http://graph.facebook.com/\(userID)/picture?type=large" as String
guard let userEmail: String = data["email"] as? String else {
print("Can't pull email from JSON")
print("Error: \(String(describing: error))")
return
}
// initial # posts = 0
let values = ["name": userName, "email": userEmail, "facebookID": userID, "profPicString": imgURLString] as [String : Any]
// update database with new user
usersReference.updateChildValues(values, withCompletionBlock: { (err, ref) in
// error in database save
if err != nil {
print(err ?? "Error saving user to database")
return
}
})
}
})
self.dismiss(animated: false, completion: nil)
// Present the main view
if let viewController = self.storyboard?.instantiateViewController(withIdentifier: "Customer Profile") {
UIApplication.shared.keyWindow?.rootViewController = viewController
self.dismiss(animated: true, completion: nil)
}
}
}
}
})
Using Swift 5 I found the email inside providerData which is an array of FIRUserInfo:
if AccessToken.current != nil {
let credential = FacebookAuthProvider.credential(withAccessToken: AccessToken.current!.tokenString)
Auth.auth().signIn(with: credential) { (res, err) in
if err != nil || res == nil {
//...
return
}
guard let providerData = res?.user.providerData else {
//...
return
}
for firUserInfo in providerData {
print(firUserInfo.providerID)
print(firUserInfo.email ?? "Email not found")
}
}
}
Hey guys actually i am trying two things here:- trying to create a new account and trying to open a screen like which appears after login but it is showing "email already exist error".
#IBAction func CreateAcccountButton(_ sender: AnyObject) {
guard let eventInterest = textBox.text,let email = EmailTestfield.text, let password = PasswordTestfield.text, let name = UsernameTestfield.text else {
print("Form is not valid")
return
}
Auth.auth().createUser(withEmail: email, password: password, completion: { (user, error) in
if let error = error {
print(error)
return
}
guard let uid = user?.uid else {
return
}
//successfully authenticated user
let imageName = UUID().uuidString
let storageRef = Storage.storage().reference().child("profile_images").child("\(imageName).png")
if let uploadData = UIImagePNGRepresentation(self.Profilepicture.image!) {
storageRef.putData(uploadData, metadata: nil, completion: { (metadata, error) in
if let error = error {
print(error)
return
}
print (metadata)
// let downloadURL = metadata?.downloadURL()
// print("URL ", downloadURL)
if let Profilepictureurl = metadata?.downloadURL()?.absoluteString {
let values = ["name": name, "email": email,"EventInterest":eventInterest,"Password":password,"Profilepictureurl": Profilepictureurl ]
let user = User(dictionary: values as [String : AnyObject])
let customViewController = MessagesController()
customViewController.setupNavBarWithUser(user)
customViewController.fetchUserAndSetupNavBarTitle()
// customViewController.navigationItem.title = values["name"] as? String
self.dismiss(animated: true, completion: nil)
self.registeruserintoDb(uid,values: values as [String : AnyObject])
}
})
}
}
)
}
fileprivate func registeruserintoDb(_ uid: String, values: [String: AnyObject]) {
let ref = Database.database().reference()
let usersReference = ref.child("users").child(uid)
usersReference.updateChildValues(values, withCompletionBlock: { (err, ref) in
if err != nil {
print(err!)
return
}
})
}
It's exactly what the error says, you already have a user with that email. Instead, use the auth.signIn method and check for currently signed in users.