Прежде всего, если у пользователей уже есть username
, он уникален и никуда не денется, я бы рекомендовал вам отказаться от использования простого входа uid
s. Это не создаст ничего, кроме проблем, связанных с переключением между ними, как вы уже здесь обнаружили. Изучите создание собственных токенов с помощью такого инструмента, как firebase-паспорт-логин, а затем сохраните записи username
.
Но поскольку это был не ваш вопрос, давайте решим его, пока мы здесь, поскольку вы можете пойти дальше и войти в тернистый вереск двойных идентичностей, через который я проходил много раз.
Чтобы сделать имя пользователя уникальным, сохраните индекс имен пользователей.
/users/$userid/username/$username
/usernames/$username/$userid
Чтобы гарантировать их уникальность, добавьте следующее правило безопасности к идентификатору пользователя в usernames / path, которое гарантирует, что для каждого имени пользователя может быть назначен только один пользователь и что значением является идентификатор пользователя:
".write": "newData.val() === auth.uid && !data.exists()"
Теперь убедитесь, что они совпадают, добавив к имени пользователя в записи users / следующее:
"users": {
"$userid": {
"username": {
".validate": "root.child('usernames/'+newData.val()).val() === $userid"
}
}
}
Это обеспечит уникальность идентификаторов. Будьте осторожны с правами чтения. Возможно, вы захотите полностью их избежать, поскольку не хотите, чтобы кто-либо просматривал личные электронные письма или имена пользователей. Что-то вроде того, что я продемонстрировал в поддержке для их сохранения, было бы идеально.
Идея здесь в том, что вы пытаетесь назначить имя пользователя и адрес электронной почты, если они не удаются, значит, они уже существуют и принадлежат другому пользователю. В противном случае вы вставляете их в запись пользователя, и теперь пользователи проиндексированы по 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"
}
},
}
}
person
Kato
schedule
15.08.2014