Reputation: 424
This is a very simple question. I have a lookup location where I store whether username has been taken. The format is username:userid its all good when I don't want to keep my db clean but I do. To stop it from ever growing I added this - it works but it feels like a very hacky approach.
this.db.database.ref('usernames').on('child_added',snapshot => {
if (snapshot.val() === userId && snapshot.key !== username) {
this.db.object(`usernames/${snapshot.key}`).remove();
}
});
It works fine does what I want it to do but it feels very very "dirty" if you know what I mean.
There must be a better way to remove all records which key !== new_key and value === $uid.
Upvotes: 0
Views: 48
Reputation: 9411
I think I understand what you are doing. You have a branch of your database called "usernames", under which you have a list of key-value pairs. The keys are usernames, short memorable names made up by users, for example "bob1" or "darthVader111". For each, the value is the Firebase UserId of the user, which is the long unmemorable code such as "4jkh53kjh543g3ij4534k5j43h5k".
database
usernames
bob1 (key): 4jkh53kjh543g3ij4534k5j43h5k (value)
darthvader (key): 098769456435k6645kjhlsdfkjh (value)
...
Your code is waiting for any additions to the usernames branch of your database, and looking at the key-value pair that is added. If you are currently logged in as Firebase UserID "4jkh53kjh543g3ij4534k5j43h5k", and your username is "bob1", and the code sees a new child being added, whose username is "Roberto", with the same Firebase UserID "4jkh53kjh543g3ij4534k5j43h5k", then it knows know that the user (whose Firebase UserID is constant) must have changed his/her username.
It is therefore reasonable to delete the (old) username entry, {"bob1": "4jkh53kjh543g3ij4534k5j43h5k"}.
I think it is ingenious because it doesn't require searching. Wouldn't it be neater, though, not to have to wait for "child_added", but instead do it in the code that creates the new username entry? For example:
let userObject={};
userObject[newUserName]=userId;
this.db.object(`usernames/${oldUserName}`).remove()
.then(this.db.object("usernames").update(userObject))
It looks like you are letting the end-user write, effectively anywhere he/she likes, into the usernames
tree. You could make it more secure with Validation rules at the firebase server.
In particular, you would probably want to prevent the end-user (who may be able to manipulate the javascript to remove the ".remove()" call) from taking over vast numbers of user Ids.
One solution for this is to have two username
databases: one keyed as you have done, as username:userId, and the other userId:username. You can set validation rules that an update must
This way, if the user removes the ".remove()" call in the javascript, he/she will not be able to take over a new userId.
Upvotes: 1