2016-06-15 14 views
6

Mam aplikację, która po użyciu autoryzacji Firebase użytkownika zapisuje dane w bazie danych Firebase. Przed zapisaniem danych chcę sprawdzić, czy nazwa użytkownika, którą podał użytkownik, już istnieje w bazie danych. Więc jeśli nie istnieje, mogę dać użytkownikowi tę unikalną nazwę użytkownika (jak każdy użytkownik ma unikalną nazwę użytkownika). Mam więc textField gdzie użytkownik wprowadza swoją nazwę użytkownika, a następnie naciśnij Dalej. Następnie aplikacja powinna sprawdzić, czy nazwa użytkownika istnieje, czy nie, i powiedzieć użytkownikowi, czy musi ją zmienić.Sprawdź, czy użytkownik istnieje z firebase 3.0 + swift

Więc kod użyłem, aby sprawdzić, czy nazwa użytkownika istnieje:

 let databaseRef = FIRDatabase.database().reference() 

     databaseRef.child("Users").observeSingleEventOfType(.Value, withBlock: { (snapshot) in 

      if snapshot.hasChild(self.usernameTextField.text!){ 

       print("user exist") 

      }else{ 

       print("user doesn't exist") 
      } 
     }) 

Więc za każdym razem obok przycisku, kod ten jest tzw. Problem polega na tym, że wynik zawsze pozostaje taki sam jak pierwszego wyszukiwania (nawet po zmianie wartości textField). Na przykład, jeśli przeszukuję Jose, a Jose istnieje w mojej bazie danych, wydrukuje "użytkownik istnieje". Ale kiedy zmienię textField na nazwę, która nie istnieje, nadal pokazuje "użytkownik istnieje".

+0

Dobrze słyszeć, że znalazłeś błąd. Zapoznaj się także z tym pytaniem, aby uzyskać dodatkowe informacje, gdy użytkownicy mogą zgłaszać unikalną nazwę użytkownika: http://stackoverflow.com/questions/25294478/how-do-you-prevent-duplicate-user-properties-in-firebase –

Odpowiedz

4

zorientowali się, że trzeba zmienić .Value do FIRDataEventType.Value

if (usernameTextField.text?.isEmpty == false){ 
     let databaseRef = FIRDatabase.database().reference() 

     databaseRef.child("Users").observeSingleEventOfType(FIRDataEventType.Value, withBlock: { (snapshot) in 

      if snapshot.hasChild(self.usernameTextField.text!){ 

       print("true rooms exist") 

      }else{ 

       print("false room doesn't exist") 
      } 


     }) 
+2

Czy nie potrwa to dłużej, jeśli więcej użytkowników będzie mieć w bazie danych? – WYS

+0

Tak, masz rację. Być może mądrzejszym sposobem na zrobienie tego jest posiadanie "równego" zapytania dla obserwatora. @WYS –

0
struct ModelUser { 
    var id: String 
    var name: String 

    init(data: DataSnapshot) { 
     // do init stuff 
    } 
} 

func isUserRegistered(with id: String, completion: @escaping (_ exists: Bool, _ user: ModelUser?) ->()) { 
    DatabaseReference.users.child(id).observeSingleEvent(of: .value) { (snapshot) in 
     if snapshot.exists() { 
      // user is already in our database 
      completion(true, ModelUser(data: snapshot)) 
     } else { 
      // not in database 
      completion(false, nil) 
     } 
    } 
} 

ten pracował dla mnie w podobnej sytuacji jak ty. Możesz także pójść w ten sposób Rx.

enum CustomError: Error { 
    case userNotRegistered 

    var localizedDescription: String { 
     switch self { 
     case .userNotRegistered: 
      return "Dude is not registered..." 
     } 
    } 
} 

func isUserRegistered(with id: String) -> Observable<(ModelUser)> { 
    let reference = DatabaseReference.users.child(id) 

    return Observable<ModelUser>.create({ observer -> Disposable in 
     let listener = reference.observe(.value, with: { snapshot in 
      if snapshot.exists() { 
       observer.onNext(ModelUser(data: snapshot)) 
       observer.onCompleted() 
      } else { 
       observer.onError(CustomError.userNotRegistered) 
      } 
     }) 
     return Disposables.create { 
      reference.removeObserver(withHandle: listener) 
     } 
    }) 
} 

Klucz w obu przypadkach używa metody .exists() migawki.