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]; }