まず第一に、ユーザーがすでに を持っている場合username
、それはユニークであり、これがなくならない場合は、単純なログイン の使用をあきらめることをお勧めしますuid
。ここですでに発見したように、これは 2 つの間を行ったり来たりしようとする問題を引き起こすだけです。firebase-passport-loginなどのツールを使用して独自のトークンの作成を調査し、 .username
しかし、それはあなたの質問ではなかったので、私たちがここにいる間に解決しましょう.
ユーザー名を一意にするには、ユーザー名のインデックスを保存します。
/users/$userid/username/$username
/usernames/$username/$userid
それらが一意であることを確認するには、usernames/ パスのユーザー ID に次のようにセキュリティ ルールを追加します。
".write": "newData.val() === auth.uid && !data.exists()"
users/ レコードのユーザー名に次を追加して、それらが一致するように強制します。
"users": {
"$userid": {
"username": {
".validate": "root.child('usernames/'+newData.val()).val() === $userid"
}
}
}
これにより、ID が一意になります。読み取り権限には注意してください。プライベートなメールやユーザー名を誰かに調べてほしくないので、それらを完全に避けたいと思うかもしれません. これらの保存をサポートするために私が示したようなものが理想的です。
ここでの考え方は、ユーザー名と電子メールを割り当てようとして失敗した場合、それらは既に存在し、別のユーザーに属しているということです。それ以外の場合は、それらをユーザー レコードに挿入すると、ユーザーは uid と電子メールでインデックス付けされます。
SOプロトコルに準拠するために、その要点からのコードを次に示します。これは、リンクから読む方が適切です。
var fb = new Firebase(URL);
function escapeEmail(email) {
return email.replace('.', ',');
}
function claimEmail(userId, email, next) {
fb.child('email_lookup').child(escapeEmail(email)).set(userId, function(err) {
if( err ) { throw new Error('email already taken'); }
next();
});
}
function claimUsername(userId, username, next) {
fb.child('username_lookup').child(username).set(userId, function(err) {
if( err ) { throw new Error('username already taken'); }
next();
});
}
function createUser(userId, data) {
claimEmail(userId, data.email, claimUsername.bind(null, userId, data.username, function() {
fb.child('users').child(userId).set(data);
);
}
そしてルール:
{
"rules": {
"users": {
"$user": {
"username": {
".validate": "root.child('username_lookup/'+newData.val()).val() === auth.uid"
},
"email": {
".validate": "root.child('email_lookup').child(newData.val().replace('.', ',')).val() === auth.uid"
}
}
},
"email_lookup": {
"$email": {
// not readable, cannot get a list of emails!
// can only write if this email is not already in the db
".write": "!data.exists()",
// can only write my own uid into this index
".validate": "newData.val() === auth.uid"
}
},
"username_lookup": {
"$username": {
// not readable, cannot get a list of usernames!
// can only write if this username is not already in the db
".write": "!data.exists()",
// can only write my own uid into this index
".validate": "newData.val() === auth.uid"
}
},
}
}