2017-08-12 2 views
1

Ich verwende Firebase, um Benutzerdatensätze zu speichern. Wenn sich ein Benutzer anmeldet, versuche ich, den Datensatz zu ziehen und ein Benutzerobjekt zu erstellen, das zwischen den Ansichtscontrollern herumläuft, anstatt die Datenbank mehrmals zu treffen.Erstellen Sie ein Objekt aus Firebase-Datenbank

class User: NSObject { 
    var name: String? 
    var email: String? 
} 

Ich habe eine Variable, myUser: User? in meinem Controller und möchte den Rekord von Feuerbasis zu dieser Variablen abgerufen zuzuweisen.

func retrieveUserWith(uid: String) { 
    Database.database().reference().child("users").child(uid).observe(.value, with: { (snapshot) in 

     if let dictionary = snapshot.value as? [String: Any] { 
      let user = User() 

      user.name = dictionary["name"] as? String 
      user.email = dictionary["email"] as? String 

      self.myUser = user 
     } 
    }) 
} 

Jetzt verstehe ich, dass die Feuerbasis Aufruf asynchron ist, und ich kann die erstellte Benutzer myUser Variable nicht direkt zugeordnet werden, wie oben gezeigt.

Gibt es eine andere Möglichkeit, user zu myUser zuzuweisen, um zu vermeiden, jedes Mal, wenn ich die View-Controller umschalte, die Datenbank zu treffen?

Antwort

1

Dies ist nicht der richtige Weg, um die gewünschten Informationen zu erhalten. Firebase bietet bereits eine sharedInstance des Benutzers an.

if let user = Auth.auth().currentUser { 
     let name = user.displayName // should check that this exists 
     let email = user.email // should check that this exists 
} 

Dennoch, dies ist die Art und Weise erreichen Sie dies tun suchen, um:

class User: NSObject { 
     var name: String 
     var email: String? 

     static var sharedInstance: User! 

     init(name: String, email: String) { 
      self.name = name 
      self.email = email 
     } 

    } 

Anrufe an Feuerbasis sind asynchron, so dass Sie einen completionHandler haben sollen, dass der Anruf genannt wird erhalten, wenn fertig ist:

func retrieveUserWith(uid: String, completionHandler: @escaping() ->()) { 
     Database.database().reference().child("users").child(uid).observe(.value, with: { (snapshot) in 

      if let dictionary = snapshot.value as? [String: Any] { 

       let name = dictionary["name"] as? String ?? "" 
       let email = dictionary["email"] as? String ?? "" 

       let user: User = User(name: name, email: email) 
       User.sharedInstance = user 
       completionHandler() 
      } 
     }) 
    } 

dann die sharedInstance des Benutzers zu verwenden, an anderer Stelle in Ihrer Anwendung können Sie folgendes tun:

if let user = User.sharedInstance { 
    // do stuff here 
} 
+0

Ich kann die Firebase-Methode nicht verwenden. Obwohl ich nur Name und E-Mail in der Frage aufgelistet habe, habe ich viele andere Eigenschaften und keine Möglichkeit, mit den Autorisierungsmethoden von Firebase darauf zuzugreifen. Soweit der Completion-Handler, das ist, was ich derzeit versuche, zu verbessern. Ich mache den Datenbankaufruf und das Setup des Controllers mit dem Beendigungshandler. Wenn der Benutzer Controller wechselt, muss ich die Datenbank mit einer anderen Anfrage treffen. – Hutch

+0

Machen Sie den Aufruf in AppDelegate, und verwenden Sie dann die sharedInstance für alle Unterschiede in ViewControllern. – rMickeyD

+0

Dies funktioniert nicht. Wenn die App zum ersten Mal geöffnet wird, muss ich die Navigationsleiste mithilfe der Informationen für angemeldete Benutzer einrichten. Obwohl ich eine gemeinsam genutzte Instanz erstellen kann, ist die gemeinsam genutzte Instanz zur Laufzeit null. – Hutch

Verwandte Themen