0

私はFacebookのログイン用にChrisの答えを実装しようとしています:Can I make Firebase use a username login process?しかし、私はその周りに私の頭を得ることはできません。Firebaseのユニークなユーザー名

これまでのところ、textFieldに条件を設定しようとしましたが、Firebaseオブザーバが非同期で動作するため、データベースにユーザ名が存在するかどうかをチェックする条件は機能しません。

let usernameString = usernameTextField.text 
let uid = FIRAuth.auth()?.currentUser?.uid 

ref.runTransactionBlock({ (currentData: FIRMutableData) -> FIRTransactionResult in 
    if var post = currentData.value as? [String : AnyObject], let uid = FIRAuth.auth()?.currentUser?.uid { 

     let usernamesDictionary = post["usernames"] as! NSDictionary 
     for (key, _) in usernamesDictionary { 
      if key as? String == usernameString { 
       print("username not available: \(key)") 
      } 
      else if usernameString == "" { 
       print("Uh oh! Looks like you haven't set a username yet.") 
      } 
      else if key as? String != usernameString { 
       print("username available: \(key)") 
       print("All set to go!") 

       let setValue: NSDictionary = [usernameString!: uid] 
       post["usernames"] = setValue 
       currentData.value = post 
      } 
     } 
     return FIRTransactionResult.successWithValue(currentData) 
    } 
    return FIRTransactionResult.successWithValue(currentData) 
} 

は、それから私は、データベース内の作成/ユーザー名/ノードを試みたとしてルールを設定:今では私がデータベースに任意のユーザー名を設定できません

{ 
    "rules": { 
    "usernames": { 
     ".read": "auth != null", 
     ".write": "newData.val() === auth.uid && !data.exists()" 
    } 
    } 
} 

。ルールを作成するのは混乱しますが、私の主なポイントは、データベースの各ユーザーに固有のユーザー名データを使用したサインアップフローが必要だということです。

+0

なぜユーザー名をユニークにしようとしていますか? Firebase Authは、電子メール/パスワードを含む数多くのプロバイダをサポートしています。作成されたすべてのアカウントに対して一意のUIDが生成されます。 – FibreChips

+0

@FibreChipsはい、しかしそれらは自動的に生成されたユニークなIDであり、ユーザーが選択したユーザー名では設定できません。 – waseefakhtar

+0

あなたの現在のアプローチについては何が問題になりませんか?トランザクションブロックは(潜在的には複数回)起動する必要がありますが(セキュリティルールと組み合わせると)最終的にユーザー名を安全に要求できるようになります。 –

答えて

0

私が関連記事で見つけたすべての答えを試している間に、簡単な方法でFirebaseルールを作成したり、データベースに別のユーザー名ノードを作成したりすることなく簡単な方法でif/else条件を入れなかったFirebase Observerではなく、FIRDataSnapshotのexists()メソッドを使用します。

ここではトリックですが、単純なオブザーバでexist()メソッドだけを試しましたが、それは私を助けませんでした。私がやったことは、クエリをフィルタリングするqueryEqualToValueでユーザ名と一致し、その後、順番に最初のクエリのユーザ名だった:

refUsers.queryOrderedByChild("username").queryEqualToValue(usernameString).observeSingleEventOfType(.Value , withBlock: { 
      snapshot in 

      if !snapshot.exists() { 
       if usernameString == "" { 
        self.signupErrorAlert("Uh oh!", message: "Looks like you haven't set a username yet.") 
       } 
       else { 

        // Update database with a unique username. 

       } 
      } 
      else { 
       self.signupErrorAlert("Uh oh!", message: "\(usernameString!) is not available. Try another username.") 
      } 

     }) { error in 
      print(error.localizedDescription) 

     } 
    } 

は、これは私のために働いた、ここでの回答のほとんどのうち最初の時間です。しかし、今のところ、これが拡大するかどうかはわかりません。あなたの経験とベストプラクティスを投稿してください。彼らは高く評価されます。

関連する問題