2017-02-08 7 views
1

次のFirebaseのクエリでは、ユーザー名がデータベースにすでに存在するかどうかを確認します。私は、usernameAlreadyExistsという変数にブール値(真)を割り当てたいと思います。しかし、私はクロージャの外側で新しい変数を使ってこの変数にアクセスする必要があります。私は、これを行うためにcompletionHandlerまたはコールバックを実装する必要があることを読んでいます。しかし、私はFirebaseクエリ構文でこれを実装する方法がわからない:Firebase閉鎖のアクセス変数

var usernameAlreadyExists = false 

FIRDatabase.database().reference().child("usernames").queryOrderedByValue().queryEqual(toValue: self.username.text).queryLimited(toFirst: 1).observe(.childAdded, with: { snapshot in 

     // Username unavailable, chose another one 
     self.invalidUsernameMsg.text = "This username already exists, please choose another one." 
     print(snapshot) 
     print(snapshot.value) 
     usernameAlreadyExists = true 

}) 

print(usernameAlreadyExists) 

プリント(usernameAlreadyExists) - >私は、このラインが「真」印刷したいが、それがために「偽」印刷します上記のコードは非同期に実行されます。

何か助けが歓迎されています。ありがとうございました!

答えて

1

userNameAlreadyExists変数を印刷すると、正しいと判断されるため、falseの値が表示されます。プログラムはあなたのコードを非常に速く印刷しますが、Firebaseがクエリを終了すると、userNameAlreadyExistsの値をtrueに変更します。

これは明確ですか?

また、コールバックまたは補完ハンドラの場合、Firebaseコードにこれがあります。部分snapshot inは完了ハンドラの始まりです。

あなたがtrueにあなたの変数を印刷したい場合には、そのように、完了ハンドラ内でそれを置く:

var usernameAlreadyExists = false 

FIRDatabase.database().reference().child("usernames").queryOrderedByValue().queryEqual(toValue: self.username.text).queryLimited(toFirst: 1).observe(.childAdded, with: { snapshot in 

     // Username unavailable, chose another one 
     self.invalidUsernameMsg.text = "This username already exists, please choose another one." 
     print(snapshot) 
     print(snapshot.value) 
     usernameAlreadyExists = true 
     print(usernameAlreadyExists) 
}) 

EDIT:OPは、登録する前に、既存のかどうユーザー名を検証したいと考えています。

  1. ユーザーが名テキストフィールド内 リファレンス入力を停止したときに検出:関数の内部https://stackoverflow.com/a/29763089/3231194

  2. 上記の検出を、あなたがそうのように、あなたの質問に掲示を使用しているあなたのFirebase機能を入れて、 :

    func userDidStopTypingUsername() { 
        // Firebase query here. 
        // Then if existing, do something and store the value too in your bool variable. 
    } 
    
  3. また、あなたの申し込みボタンのあなたのIBActionや関数の内部で、を検証も。既存の場合は、何かをしてからサインアップを続行しないようにしてください。それ以外の場合は続行します。

+0

prettyitgirl.comの説明に感謝します!しかし、私はクロージャの外側でこの変数にアクセスする必要があります。私はこれを** print()**で表現しています。これは現在の例では、コードが持つべき振る舞いを反映しています。しかし、後で、私は自分のコードで変数の変更された値(偽から真)を使う必要があります。変数の値に応じていくつかのコードを実行する必要があります:** if usernameAlreadyExists {//何か} else {//何か他のもの} **。これを達成する方法はありますか?再度、感謝します! – ayarem502

+0

こんにちは、私は**あなたの**サインアップのための 'usernames'のこの検証をしていると思いますよね?または、ユーザーがtextFieldで入力を完了するか、入力を停止するとすぐにユーザー名をすぐに検証したいですか? – Glenn

+0

それは正しいです。ユーザーが登録される前にユーザー名を検証したいと思います。ユーザーの情報は、サインアッププロセスの最後にデータベースに書き込まれるという考え方です。こうすることで、登録プロセスの途中でユーザーがアプリを強制終了すると、DBにデータが書き込まれなくなります。上記のコードは、ユーザ名がすでにリアルタイムで取得されているかどうかを検出します。しかし、ユーザ名が取得されていないかどうかを確認する方法が必要です。Firebaseのクエリではこれを行うことができません。なぜ上記のクエリの結果を得て参照として使用したいのですか? 。 – ayarem502