2016-07-30 8 views
3

Ich bin so nah an diesen Teil meines Projekts zu erreichen. Ich habe viel gelernt, aber ich kann es einfach nicht sehen. Was ich versuche, ist im Wesentlichen zu überprüfen, ob eine E-Mail-Adresse bereits von einem anderen Benutzer verwendet wird. Um dies zu erreichen, verwende ich diesen Code:iOS Async Aufgabe Problem beim Zurückgeben Firebase Benutzernamen

func emailCheck(input : String, result:(canRegister: Bool?) -> Void){ 
    var canRegister : Bool? 
    FIRAuth.auth()?.signInWithEmail(input, password: " "){(user, error) in 
     if error != nil { 
      if(error?.code == 17009){ 
       print("Wrong Password") 
       canRegister = false 
      }else if(error?.code == 17011){ 
       print("Unknown User") 
       canRegister = true 
      }else{ 
       canRegister = false 
      } 
     } 
    } 
} 

Diese ganze Async Sache nur 6 Stunden alt für mich ist, also, wenn Sie irgendwelche Vorschläge haben, bitte lassen Sie mich wissen. Aber diese Funktion wird dann aufgerufen, wenn eine Taste gedrückt wird, nur durch dies zu tun:

print(emailCheck(emailTxt.text!){(canRegister : Bool?) -> Void in}) 

Aus irgendeinem Grund, diese leer zurückkehrt, nicht true, false oder sogar nil. Es gibt nur () zurück Es gibt jedoch Wrong Password zurück, wenn ich das richtige Passwort passiere, nicht ganz sicher, ob das relevant ist. Kann jemand damit Hand anlegen? Danke an alle!

Added Info Nach Vorschlägen der Code und der Verweis auf den Code sieht nun wie folgt aus: (nur wichtige Teile enthalten)

class LoginViewController: UIViewController { 
@IBAction func nextScreen(sender: UIButton) { 
emailCheck(emailTxt.text!) { isValid in 
       if isValid { 
        print("Valid!") 
       } else { 
        print("Invalid!") 
       } 
      } 
} 
func emailCheck(input: String, callback: (isValid: Bool) -> Void) { 
    FIRAuth.auth()?.signInWithEmail(input, password: "") { (user, error) in 
     var canRegister = false 

     if error != nil { 
      if (error?.code == 17009) { 
       //wrong password error 
      } else if(error?.code == 17011) { 
       //email doesn't exist 
       canRegister = true 
      } 
     } 

     callback(isValid: canRegister) 
    } 
} 

Der obwohl Prozess dahinter ist, dass, wenn der Code zurückgegeben wird, dass der Benutzer nicht existiert, dann ist das E-Mail-Konto offen, so dass canRegister erlaubt wird, andernfalls, wenn das leere Passwort falsch eingegeben wurde, dann wissen wir, dass das Konto existiert und daher nicht für die Registrierung geöffnet ist verwenden. Derzeit canRegister gibt den Wert gleich, was es wie hier definiert ist:

var canRegister = false 

Zurück im Funktionsaufruf.

+0

Der aktualisierte Code mir richtig aussieht. Aus irgendeinem Grund scheint es, dass Sie von Firebase keinen Fehlercode 17011 erhalten. Wenn ich mir ihre Dokumente ansehe, denke ich, dass sich ihre API nicht so verhält, wie Sie es erwarten. Laut [dieser Seite] (https://firebase.google.com/docs/reference/ios/firebaseauth/interface_f_i_r_auth_errors) ist der Fehler "FIRAuthErrorCodeUserNotFound" (der dem von Ihnen verwendeten Code 17011 entspricht) _ "Gibt an, dass das Benutzerkonto nicht vorhanden war Das kann passieren, wenn der Benutzeraccount gelöscht wurde. "_ Es ist mir nicht klar, ob das der einzige Fall ist, in dem dieser Fehler ausgelöst wird ... – dbburgess

+0

In jedem Fall, um mehr auf die Wurzel von dem zu bekommen, was Sie versuchen tu ... Es sieht so aus, als würdest du versuchen, mit etwas fertig zu werden, das sie für dich behandeln. Die [docs] (https://firebase.google.com/docs/reference/ios/firebaseauth/interface_f_i_r_auth.html#aeaee7fcef878990954f8e72f7278cd7d) für die 'createUserWithEmail'-Methode sagen, dass sie einen 'FIRAuthErrorCodeEmailAlreadyInUse'-Fehler auslösen kann, was so aussieht ist was du versuchst mit dir selbst umzugehen. Warum nicht einfach versuchen, es zu erstellen und stattdessen diesen Fehler zu behandeln? – dbburgess

+1

@dbburgess Sie wissen, was es war? Mir fehlte ein Leerzeichen in dieser Zeile: '... signInWithEmail (input, password:" ") ...' Da 'password' keinen Platz hatte, wurde es von der firebase nicht als leeres Passwort gelesen, sondern eher wie ein 'nil', das würde dann keinen Fehler werfen. Danke für all deine Hilfe! – Ethan

Antwort

1

Sie drucken den Rückgabewert emailCheck, was nicht ganz Ihren Vorstellungen entspricht. Async bedeutet nur, dass ein Teil des Codes zu einem späteren Zeitpunkt ausgeführt wird. Betrachten Sie diese einfache Funktion:

func emailCheck(input: String) -> Bool { 
    var valid = true 

    if input.characters.count == 0 { 
    valid = false 
    } 

    return valid 
} 

Dies überprüft einfach, ob eine E-Mail mehr als null Zeichen hat. Es könnte erheblich vereinfacht werden, aber ich habe es etwas ausführlicher gemacht, um die Unterschiede zu verdeutlichen. Um es zu nutzen, würde man einfach etwas tun:

let isValid = emailCheck("[email protected]") 

if isValid { 
    print("Valid!") 
} else { 
    print("Invalid!") 
} 

Wenn wir das Verfahren in der Lage sein zu tun Arbeit asynchron wollen, würden wir es einen Rückruf geben. Ein Callback ist nur eine Funktion, die aufgerufen werden kann, um uns mitzuteilen, was die Ergebnisse waren, anstatt dass sie direkt von der Funktion zurückgegeben werden. Hier ist, wie das aussieht:

func emailCheck(input: String, callback: (isValid: Bool) -> Void) { 
    var valid = true 

    if input.characters.count == 0 { 
     valid = false 
    } 

    callback(isValid: valid) 
} 

func callback(isValid: Bool) { 
    if isValid { 
     print("Valid!") 
    } else { 
     print("Invalid!") 
    } 
} 

emailCheck("[email protected]", callback: callback) 

Beachten Sie, dass emailCheck nicht mehr kehrt ein Wert, aber tatsächlich führt die Callback-Methode mit dem Ergebnis. Dies ist noch nicht wirklich asynchron, weil der Callback sofort ausgeführt wird, aber wir können asynchrone Dinge tun, wenn wir wollen.

Swift hat einige nette syntaktische Zucker für die Weitergabe von Callbacks als letzten Parameter, ohne sie explizit wie oben zu deklarieren. Dies verwenden Sie für die Firebase-Methode signInWithEmail.Mit der in diesem Code, sieht es wie folgt aus:

emailCheck("[email protected]") { isValid in 
    if isValid { 
     print("Valid!") 
    } else { 
     print("Invalid!") 
    } 
} 

Es tut genau das Gleiche, aber ich denke, es ist in diesem Fall ein wenig schöner aussieht. Jetzt haben wir also ein gutes Setup, das die E-Mail und etwas Code überprüfen kann, der später ausgeführt werden kann, sobald wir wissen, ob die E-Mail gültig ist oder nicht. Dass sie alle zusammen:

func emailCheck(input: String, callback: (isValid: Bool) -> Void) { 
    FIRAuth.auth()?.signInWithEmail(input, password: " ") { (user, error) in 
     var canRegister = false 

     if error != nil { 
      if (error?.code == 17009) { 
       print("Wrong Password") 
      } else if(error?.code == 17011) { 
       print("Unknown User") 
       canRegister = true 
      } 
     } 

     callback(isValid: canRegister) 
    } 
} 


var availableEmail = false 

emailCheck("[email protected]") { isValid in 
    if isValid { 
     print("Valid!") 
    } else { 
     print("Invalid!") 
    } 

    availableEmail = isValid 
    // This prints **second**, and should print `true`, if `isValid` was true. 
    print(availableEmail) 
} 

// This prints **first**, and should print `false`, because the callback likely has not run yet. 
print(availableEmail) 

Edit: anzeigen print Code/Bemerkungen darüber zeigen, wie eine Variable nicht sofort aktualisiert, wenn Sie eine Callback-Methode verwenden.

Zusätzliche edit: Eine andere Möglichkeit, es zu strukturieren, eine andere Funktion für Klarheit mit:

emailCheck("[email protected]") { isValid in 
    if isValid { 
     print("Valid!") 
    } else { 
     print("Invalid!") 
    } 

    self.emailCheckComplete(isValid) 
} 

func emailCheckComplete(availableEmail: Bool) { 
    // This is the same as above, but perhaps helps you follow the flow. 
    print(availableEmail) 
} 
+1

Nun, ja, 'isValid' ist Typ' Bool', also könntest du 'callback (isValid: true)' machen, aber was ist, wenn die Email genommen wird? Sie möchten falsch verwenden. Deshalb habe ich 'canRegister' verwendet, was auch ein' Bool' ist und entsprechend auf true/oder false gesetzt ist. – dbburgess

+1

In meinem Beispiel gibt 'emailCheck' keinen _any_ Wert zurück, vielleicht verstehe ich aber nicht, was Sie meinen. – dbburgess

+1

Können Sie Ihren Post mit dem, was Sie geändert haben, basierend auf meinem Beispiel bearbeiten? Es wäre hilfreich, den aktualisierten Code zu sehen, um zu verstehen, was Sie meinen. – dbburgess