Swift 2.0 Parse Login - swift

So I've been attempting to update my code to Swift 2.0 syntax, but I can't seem to get my Parse login to work. I looked over the documentation changes and added the result block for my login, but I'm getting the error "'(, ) throws -> Void' is not convertible to 'PFUserResultBlock?'"
Here is the line of code:
PFUser.logInWithUsernameInBackground(usernameTextField.text!, password: passwordTextField.text!, block: { (user,error) -> Void in
if user != nil {

This Code might solve your problem.
PFUser.logInWithUsername(inBackground: emailTextField.text!, password: passwordTextField.text!, block: { (user, error) in
self.activityIndicator.stopAnimating()
UIApplication.shared.endIgnoringInteractionEvents()
if error != nil {
var displayErrorMessage = "Please try again later"
let error = error as NSError?
if let errorMessage = error?.userInfo["error"] as? String {
displayErrorMessage = errorMessage
}
self.createAlert(title: "Login Error", message: displayErrorMessage)
} else {
print("logged inn")
self.performSegue(withIdentifier: "showUserTable", sender: self)
}
})

Try this version
PFUser.logInWithUsernameInBackground(usernameTextField.text!, password: passwordTextField.text!) { (user:PFUser?, error:NSError?) -> Void in
if user != nil {
print("Login Successful")
} else {
print("Login Failed")
}
}

Related

How to handle Firebase Auth Errors? / Swift / Firebase

Hey guys can someone tell me how to handle this? I tried a lot but if I correct the one error another one is appearing...
Thanks in advance
Auth.auth().createUser(withEmail: eMailTextField.text!, password: passwordTextField.text!) { (data, error) in
if error != nil {
if let errCode = error as NSError? {
guard let errorCode = AuthErrorCode(rawValue: error) else {
print("there was an error logging in but it could not be matched with a firebase code")
return
}
switch errorCode {
case .FIRAuthErrorCodeNetworkError:
print("No Internet Connection")
case .ErrorCodeEmailAlreadyInUse:
print("in use")
default:
print("Create User Error: \(error!)")
}
}
} else {
print("all good... continue")
}
You can bridge to NSError and then create the AuthErrorCode based on error.code:
Auth.auth().createUser(withEmail: "MyEmail", password: "MyPassword") { authResult, error in
if error != nil, let error = error as NSError? {
if let errorCode = AuthErrorCode(rawValue: error.code) {
switch errorCode {
case .invalidEmail:
break
case .emailAlreadyInUse:
break
default:
break
}
}
} else {
//no error
}
}
Note that I only listed a couple of the errorCode possibilities - there's quite an extensive list of them.

How to have code inside of a guard else statement in swift?

I have the following code:
#IBAction func loginTapped(_ sender: Any) {
let error = validateFieldsSignIn()
if error != nil {
showErrorSignIn(error!)
} else {
guard let emailsignin = emailSignIn?.text!.trimmingCharacters(in: .whitespacesAndNewlines),
let passwordsignin = passwordSignIn?.text!.trimmingCharacters(in: .whitespacesAndNewlines) else {
return showErrorSignIn("Fill in all fields")
}
Auth.auth().signIn(withEmail: emailsignin, password: passwordsignin) { (user, error) in
if error != nil {
print("There was an error")
self.errorLabel3.text = "Invalid username or password"
self.errorLabel3.alpha = 1
} else {
self.transitionToHome()
}
}
}
}
Although unless the fields aren't filled in the else statement gets triggered and the error label says fill in all fields, essential the code that is getting triggered is this:
else {
return showErrorSignIn("Fill in all fields")
}
I tried putting the Auth.auth().signIn() inside the else block although I got the following error:
Variable declared in 'guard' condition is not usable in its body
How do I fix this error message?

Firebase Re-Authenticate Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value error

The user needs to be authenticated again to change the email address. When I write the following code, I get the error: user.reauthenticate (with: credential) {_ in the line of error Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value.
var credential: AuthCredential! I have also defined this
if let user = Auth.auth().currentUser {
// re authenticate the user
user.reauthenticate(with: credential) { _,error in
if let error = error {
print(error)
} else {
// User re-authenticated.
user.updateEmail(to: self.emailField.text!) { (error) in
}
}
}
}
You need to prompt the user for their credentials, otherwise that property will be nil which will show the error you are seeing
let user = Auth.auth().currentUser
var credential: AuthCredential
// *** Prompt the user to re-provide their sign-in credentials ***
// populate the credential var with that data so it's not nil
//
user?.reauthenticate(with: credential) { error in
if let error = error {
// An error happened.
} else {
// User re-authenticated.
}
}
You can follow this example step by step
Configuration:
-> Select your project
-> Go to TARGETS
-> Select your project icon
-> Click info tab
-> Add new URL Types(REVERSED_CLIENT_ID from GoogleService-Info.plist)
1. You need to setup your pre requisite configuration into your AppDelegate class
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// Pass device token to auth
Auth.auth().setAPNSToken(deviceToken, type: AuthAPNSTokenType.unknown)
}
// For iOS 9+
func application(_ application: UIApplication, open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
if Auth.auth().canHandle(url) {
return true
}
// URL not auth related, developer should handle it.
return ApplicationDelegate.shared.application(application, open: url, options: options)
}
// For iOS 8-
func application(_ application: UIApplication,
open url: URL,
sourceApplication: String?,
annotation: Any) -> Bool {
if Auth.auth().canHandle(url) {
return true
}
// URL not auth related, developer should handle it.
return ApplicationDelegate.shared.application(application, open: url)
}
func application(_ application: UIApplication, didReceiveRemoteNotification notification: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
if Auth.auth().canHandleNotification(notification) {
completionHandler(UIBackgroundFetchResult.noData)
return
}else{
completionHandler(UIBackgroundFetchResult.newData)
}
// This notification is not auth related, developer should handle it.
}
2. It's your ViewModel class
class FirebaseSignin: NSObject {
public func firebaseSigninWith(phoneNumber: String?, completion: #escaping (Bool, String?, Error?)->()) {
//SVProgressHUD.show()
if let phoneNumber = phoneNumber {
print("firebaseSigninWith phoneNumber: ", phoneNumber)
Auth.auth().languageCode = "fr";
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) { [weak self] (verificationID, error) in
//SVProgressHUD.dismiss()
if let error = error {
completion(false, verificationID, error)
return
}else{
UserDefaults.standard.set(verificationID, forKey: "authVerificationID")
completion(true, verificationID, error)
}
}
}else{
completion(false, nil, nil)
}
}
public func otpConfirmation(verificationCode: String?, completion: #escaping (Bool, Any?, Error?)->()) {
//SVProgressHUD.show()
if let verificationCode = verificationCode {
if let verificationID = UserDefaults.standard.string(forKey: "authVerificationID") {
let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID, verificationCode: verificationCode)
Auth.auth().signIn(with: credential) { (authResult, error) in
//SVProgressHUD.dismiss()
if let error = error {
completion(false, verificationID, error)
return
}else{
completion(true, verificationID, error)
}
}
}else{
completion(false, nil, nil)
}
}else{
completion(false, nil, nil)
}
}
}
3. you call your submitBttonAction function from LoginClass
func submitBttonAction() {
let mobile_no = mobileNumberTextField.getFormattedPhoneNumber(format: .E164)
self.firebaseSignin.firebaseSigninWith(phoneNumber: mobile_no) { [weak self] (isSuccess, verificationID, error) in
if isSuccess {
//GlobalVariable.showToastWith(view: GlobalVariable.getRootViewController()?.view, message: "OTP send successfully.")
//RootViewController.selectViewController(_viewController: .OTPConfrimationViewController, ["delegate": self])
// you open your OTPConfrimationViewController
}else{
//GlobalVariable.showToastWith(view: GlobalVariable.getRootViewController()?.view, message: "OTP sending fail \(error?.localizedDescription ?? "")")
}
}
}
4. confirm your OTP from TOPViewController class
func otpConfirmation() {
if let otp = self.otpTextField.text {
self.firebaseSignin.otpConfirmation(verificationCode: otp) { [weak self] (isSuccess, authResult, error) in
if isSuccess {
//GlobalVariable.showToastWith(view: GlobalVariable.getRootViewController()?.view, message: "OTP varified successfully.")
//self?.handleHeaderBackAction(nil)
//self?.delegate?.otpConfrimationCallBack(isSuccess)
}else{
//GlobalVariable.showToastWith(view: GlobalVariable.getRootViewController()?.view, message: "OTP varification fail \(error?.localizedDescription ?? "")")
}
}
}
}

Check Firebase error and if textFields are empty before creating user

I´m trying to check for signup errors and if textFields is empty. This is kind of working, but it allows the user to register the user if the nameTextFieldand the addressTextFieldis empty. The alert poops up correctly though.
#IBAction func registerButton(_ sender: UIButton) {
Auth.auth().createUser(withEmail: emailTextField.text!, password: passwordTextField.text!, completion: { user, error in
if error != nil {
if let errCode = AuthErrorCode(rawValue: error!._code) {
switch errCode {
case .invalidEmail:
self.errorMsg(title: "Error", message: "E-mail address format wrong")
case .emailAlreadyInUse:
self.errorMsg(title: "Error", message: "E-mail is already in use")
case .weakPassword:
self.errorMsg(title: "Error", message: "Weak password. Need at least 6 characters")
default:
print("Create User Error: \(error!)")
}
}
return
} else {
//Display errormsg for missing entry
if (self.nameTextField.text?.isEmpty)! {
self.missingText(title: "Ooops", message: "Please enter your name")
if (self.addressTextField.text?.isEmpty)! {
self.missingText(title: "Ooops", message: "Please enter your address")
}
} else {
//Register userinfo in Firebase
let ref = Database.database().reference()
let usersRefrence = ref.child("users")
let uid = user?.user.uid
let newUserRefrence = usersRefrence.child(uid!)
newUserRefrence.setValue(["Name": self.nameTextField.text!, "Address": self.addressTextField.text!])
}
self.registrationConfirmation(title: "Great", message: "Please sign in with the registered user")
}
})
}
validate textfield before going to auth.
guard let email = emailTextField.text, email.isValidEmail(), let password = passwordTextField.text, password != "" else {
// show error for nil values
return
}
// go with Autth
Auth.auth().createUser(withEmail: email, password: password, completion
make an extension for validating email
extension String {
func isValidEmail() -> Bool {
// here, `try!` will always succeed because the pattern is valid
let regex = try! NSRegularExpression(pattern: "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+#[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", options: .caseInsensitive)
return regex.firstMatch(in: self, options: [], range: NSRange(location: 0, length: count)) != nil
}
}

how do I perform segue after log in with facebook account?

Currently I am attempting to perform a segue to a second view controller after a user logs in with Facebook using firebase
I was able to sort of get this to work. My problem is I have to actually log-in twice before the Segue is activated. Any suggestions?
see my CODE below
private var fbLoginSuccess = false //This is gobal
override func viewDidAppear(_ animated: Bool) {
if (FBSDKAccessToken.current() != nil && fbLoginSuccess == true)
{
performSegue(withIdentifier: "Home", sender: self)
}
}
#IBAction func facebookLogin(sender: UIButton) {
let facebookLogin = FBSDKLoginManager()
facebookLogin.logIn(withReadPermissions: ["public_profile", "email"], from: self, handler: {
(facebookResult, facebookError) -> Void in
if facebookError != nil {
print("Facebook login failed. Error \(String(describing: facebookError))")
} else if (facebookResult?.isCancelled)! {
print("Facebook login was cancelled.")
} else {
let credential = FacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
Auth.auth().signIn(with: credential) { (user, error) in
if error != nil {
print("Login failed. \(String(describing: error))")
} else {
fbLoginSuccess = true
print("Logged in!")
if (facebookResult?.grantedPermissions.contains("email"))! {
}
}
}
}
})
}
It appears that you're only calling performSegue(withIdentifier:) in viewDidAppear. If you want the segue to occur after signing in, then you need to include it there.
let facebookLogin = FBSDKLoginManager()
facebookLogin.logIn(withReadPermissions: ["public_profile", "email"], from: self, handler: {
(facebookResult, facebookError) -> Void in
if facebookError != nil {
print("Facebook login failed. Error \(String(describing: facebookError))")
} else if (facebookResult?.isCancelled)! {
print("Facebook login was cancelled.")
} else {
let credential = FacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
Auth.auth().signIn(with: credential) { (user, error) in
if error != nil {
print("Login failed. \(String(describing: error))")
} else {
fbLoginSuccess = true
print("Logged in!")
if (facebookResult?.grantedPermissions.contains("email"))! {
}
performSegue(withIdentifier: "Home", sender: self)
}
}
}
})