Firebase android:使用户名唯一
parsing将在今年年底closures,所以我决定开始使用Firebase。 我需要实现一个注册过程,有3个字段:电子邮件,用户名,密码( 电子邮件和用户名必须是唯一的我的应用程序)。
由于Firebase不提供简单的方式来pipe理像Parse这样的用户名,我决定只使用电子邮件/密码注册并保存一些额外的数据,如用户名。 这里是我的用户数据结构:
app : { users: { "some-user-uid": { email: "test@test.com" username: "myname" } } }
但是,我想要做的是使用户名独特,并在创build一个帐户之前检查它。 这些是我的规则:
{ "rules": { ".read": true, ".write": true, "users": { "$uid": { ".write": "auth !== null && auth.uid === $uid", ".read": "auth !== null && auth.provider === 'password'", "username": {".validate": "!root.child('users').child(newData.child('username').val()).exists()"} } } } }
非常感谢您的帮助
部分答案是存储一个用户名索引,在安全规则中检查:
app : { users: { "some-user-uid": { email: "test@test.com" username: "myname" } }, usernames: { "myname": "some-user-uid" } }
所以usernames
节点将用户usernames
映射到一个uid。 它本质上读为“用户名”myname“属于”some-user-uid“”。
有了这个数据结构,您的安全规则可以检查给定用户名是否已经有条目:
"users": { "$uid": { ".write": "auth !== null && auth.uid === $uid", ".read": "auth !== null && auth.provider === 'password'", "username": { ".validate": " !root.child('usernames').child(newData.val()).exists() || root.child('usernames').child(newData.val()).val() == $uid" } } }
这validation了用户名没有被任何人声明,或者它被当前用户声明。
按照Frank的build议保存用户名,但是当您保存用户名时,请使用Firebase中的runTransaction函数确保不会input用户名。 这个function是由Firebase保证是一个primefaces操作,所以你可以放心没有碰撞
firebaseRef.child("usernames").child(username).runTransaction(new Transaction.Handler() { @Override public Transaction.Result doTransaction(MutableData mutableData) { if (mutableData.getValue() == null) { mutableData.setValue(authData.getUid()); return Transaction.success(mutableData); } return Transaction.abort(); } @Override public void onComplete(FirebaseError firebaseError, boolean commited, DataSnapshot dataSnapshot) { if (commited) { // username saved } else { // username exists } } });
我还不太了解Firebase的安全性,但是我可能已经使用Java解决了这个问题。 我已经在下面发布了。
我的数据结构是
myapp { users: { <unique generated-id> { username: "example.username" } } } public boolean isUsernameExists(final String enteredUsername) { final Boolean[] isExist = {false}; FBref.child("users").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) { String existingUsername = (String) userSnapshot.child("userName").getValue(); if (existingUsername.equals(enteredUsername)) { isExist[0] = true; } } } @Override public void onCancelled(FirebaseError firebaseError) { //some error thrown here } }); return isExist[0]; }