I've created a method for auto login via Firebase but somehow my segue is not being performed..
I've this code and in my viewDidLoad I'm calling the method (ofc)
override func viewDidLoad() {
super.viewDidLoad()
//Login user automatically
autoLogin()
}
func autoLogin(){
if Auth.auth().currentUser?.email != nil{
print("not nil") //for test
self.performSegue(withIdentifier: "toRootVc", sender: self)
print("not nil1") //for test
}
else{
print("nil") //for test
}
}
The app prints both "not nil" and "not nil1" but it still does not
performing the segue.
I also have a login button which works.
func handleLogin(){
Auth.auth().signIn(withEmail: email.text!, password: password.text!) { (result, err) in
if let err = err{
print("Error logging in:", err.localizedDescription)
}
else{
self.databaseHandler.retrieveData(email: self.email.text!){
self.performSegue(withIdentifier: "toRootVc", sender: self)
}
}
}
}
But the autoLogin doesn't actually performing the segue. (Ignores the step)
Any input would be much appreciated.
Segues won't work inside viewDidLoad as it's too early try in viewWillAppear or better do this check before presenting that vc say inside didFinishLaunchingWithOptions of AppDelegate
have you tried to put this autoLogin() on viewDidAppear()
Related
I'm trying to detect when the facebook login viewcontroller gets dismissed so I can stop the loading animation. I implemented the facebook login SDK through firebase, and I'm logging in using this method:
#IBAction func facebookSignIn(_ sender: UIButton) {
loginBtn.startLoadingAnimation()
FBSDKLoginManager().logIn(withReadPermissions: ["email"], from: self) { (result, err) in
if err != nil {
print("CustomFB Login Failed: ", err)
self.loginBtn.stopLoadingAnimation()
return
}
}
}
How would I detect when the login viewcontroller gets dismissed?
This is simple, you have put stopLoadingAnimation() in the wrong place.
#IBAction func facebookSignIn(_ sender: UIButton) {
loginBtn.startLoadingAnimation()
FBSDKLoginManager().logIn(withReadPermissions: ["email"], from: self) { (result, err) in
self.loginBtn.stopLoadingAnimation()
//Facebook login is complet after Two case, failer and success.
if err != nil {
print("CustomFB Login Failed: ", err)
return
}
}
}
Stop spinner login is under if condition, but user clicks on cancel then your spinner does not stop.
#IBAction func addInformation(_ sender: UIBarButtonItem) {
// check rateHourly has value
if let editedRateHourly = rateHourly.text {
print("editedRateHourly condition is \(editedRateHourly)")
if editedRateHourly != ""{
print("not nil")
// check edit value is number?
let num = Int(editedRateHourly)
if num != nil {
print("is num")
// add to database
UserDefaults.standard.set(editedRateHourly, forKey: "\(findDate())")
UserDefaults.standard.synchronize()
// back to last viewController
navigationController?.popToRootViewController(animated: true)
}else{
print("not num")
print("error alert push!!")
popErrorAlert()
}
}else {
print("nil")
print("editedRateHourly condition is nil")
popErrorAlert()
}
}
}
#IBAction func cannelInformationPage(_ sender: UIBarButtonItem) {
navigationController?.popToRootViewController(animated: true)
}
I want to create a new simple edit page. It's two problem for me that when I finish edition if-else will check the condition is correct or not and then save the data popToRootViewControlle. When I finish edition I click on "addInformation" BarButtonItem and I get UI wrong. the Other wrong is when I click on editField but I don't enter any condition. And then I click on "cannelInformationPage" UIBarButtonItem. It also get wrong.
It's what I get wrong
wrong information
Because it returns Bool
_ = navigationController?.popToRootViewController(animated: true)
_ = self.navigationController?.popViewController(animated: true)
If you want to come back to last view controller than you can try above line, hope its work for you.
I am using Firebase for Login/Sign Up authentication but I ran into a problem. I got everything to set up and it works fine, but I am having a bit of an issue with the login part.
Here's my code:
#IBAction func clickLogin(_ sender: UIButton) {
FIRAuth.auth()?.signIn(withEmail: emailTextField.text!, password: passwordTextField.text!, completion: { (user, error) in
if let error = error {
print(error.localizedDescription)
}
})
performSegue(withIdentifier: "toMainSegue", sender: self) //Issue
}
What's wrong is that when the email or the password is incorrect, it will still perform the segue. I tried:
#IBAction func clickLogin(_ sender: UIButton) {
FIRAuth.auth()?.signIn(withEmail: emailTextField.text!, password: passwordTextField.text!, completion: { (user, error) in
if let error = error {
print(error.localizedDescription)
} else {
performSegue(withIdentifier: "toMainSegue", sender: self) //Error Line
}
})
But I get an error:
Implicit use of ‘self’ in closure, use ‘self.’ to capture semantics explicit.
Is there a better way of bring the user to the next UI if and only if login was successful?
In the code that you have shared
#IBAction func clickLogin(_ sender: UIButton) {
FIRAuth.auth()?.signIn(withEmail: emailTextField.text!, password: passwordTextField.text!, completion: { (user, error) in
if let error = error {
print(error.localizedDescription)
}
})
performSegue(withIdentifier: "toMainSegue", sender: self) //Issue
}
The performSegue(withIdentifier:sender:) method is being called within the #IBAction and not inside the completion handler of the signIn(withEmail:password:completion) method. Thus, regardless of what is written or executed in the latter, your performSegue(withIdentifier:sender:) will be called. Try modifying the code to the following
#IBAction func clickLogin(_ sender: UIButton) {
FIRAuth.auth()?.signIn(withEmail: emailTextField.text!, password: passwordTextField.text!, completion: { (user, error) in
if let error = error {
print(error.localizedDescription)
} else {
self.performSegue(withIdentifier: "toMainSegue", sender: self)
}
})
}
Keep in mind that, because the logic is being executed in a closure, you need to specify the self. prefix before methods and variables!
Any variables or methods used inside of block needs to use of ‘self’.
#IBAction func clickLogin(_ sender: UIButton) {
FIRAuth.auth()?.signIn(withEmail: emailTextField.text!, password: passwordTextField.text!, completion: { (user, error) in
if let error = error {
print(error.localizedDescription)
} else {
self.performSegue(withIdentifier: "toMainSegue", sender: self) //Error Line
}
})
Your code goes in the else part everytime your API hits successfully even if the login credentials are wrong.
The FIRAuth API must be returning some data when it gets hit, for example a string or dictionary named "success" = 1 or 0. Check in ur else part for the success to be true or false. false being wrong credentials and true being correct credentials.
The error part gets executed when there is any error in hitting the API itself like network error or the API's parameters being in wrong format or any other error.
In your case its getting hit and returning a result too. You have to check the result dictionary if your user did get logged in or not and segue onto the next controller based on that result.
Try this. This is how I do my login.
FIRAuth.auth()?.signIn(withEmail: emailField.text!, password: passwordField.text!, completion: { user, error in
if error == nil {
print("Successfully Logged IN \(user!)")
self.performSegue(withIdentifier: "signedIn", sender: self)
}
})
This just tests if there is no error with the signing in process, then performs the segue. I haven't had any trouble with it, and it seems to work great.
I'm using Facebook login in my app and I'm not able to go to next view after login completed.
i.e. TabBarController its shows an above stated error. I am doing custom login from a button. Here is my code of how I am doing login.
#IBAction func fbLoginBtn(sender: AnyObject) {
facebookLogin.logInWithReadPermissions(["email","user_friends","user_posts"],fromViewController: self, handler: { (response:FBSDKLoginManagerLoginResult!, error: NSError!) in
if error != nil {
print(error.localizedDescription)
print("Facebook login failed")
} else {
let accessToken = response.token.tokenString
print(accessToken)
print("Successfully login.\(accessToken)")
self.performSegueWithIdentifier("showMain", sender: self)
}
})
}
After login I'm performing segue to go to next view i.e. TabBarController. If anyone can help please help me. Thank you.
I'm registering new users under my application that uses facebook API and Parse. The users are being created without segueing to another view. Unfortunately, if I try to segue for a next view the user is created without the name and email info. I know this runs in background so i need a solution to know when the execution is finished. Any ideas?
override func viewDidLoad() {
FBSDKProfile.enableUpdatesOnAccessTokenChange(true)
}
override func viewDidAppear(animated: Bool) {
if let access = FBSDKAccessToken.currentAccessToken() {
PFFacebookUtils.logInInBackgroundWithAccessToken(access, block: {
(user: PFUser?, error: NSError?) -> Void in
if user != nil {
println("already registred user")
self.performSegueWithIdentifier("firstView", sender: self)
} else {
println("Uh oh. There was an error logging in.")
}
})
}
}
#IBAction func fbLoginButtonTouchUpInside (sender: AnyObject) {
PFFacebookUtils.logInInBackgroundWithReadPermissions(["public_profile", "email", "user_friends"], block: { (user, error) in
if let user = user {
User.updateUserInfo()
println("new user")
//THIS SEGUE IS CRASHING
self.performSegueWithIdentifier("newUserSegue", sender: self)
} else {
println("Uh oh. The user cancelled the Facebook login.")
}
})
}
Try this. AFAK you must perform on main thread that is why it is crashing:
dispatch_async(dispatch_get_main_queue()) {
self.performSegueWithIdentifier("newUserSegue", sender: self)
}
The problem here was that I was running another background task inside
PFFacebookUtils.logInInBackgroundWithReadPermissions
The solution was to add a completion handler to User.updateUserInfo() and perform the segue inside of it.