Firebase android:使用户名唯一

Parse将在年底关闭,所以我决定开始使用Firebase。 我需要实现一个包含3个字段的注册过程:电子邮件,用户名,密码( 电子邮件和用户名对我的应用必须是唯一的)。

由于Firebase没有像Parse那样提供管理用户名的简便方法,因此我决定只使用电子邮件/密码注册并保存一些额外的数据,如用户名。 这是我的用户数据结构:

app : { users: { "some-user-uid": { email: "test@test.com" username: "myname" } } } 

但是,我想要做的是使用户名唯一,并在创建帐户之前检查它。 这些是我的规则:

 { "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()"} } } } } 

非常感谢您的帮助

Solutions Collecting From Web of "Firebase android:使用户名唯一"

部分答案是存储您在安全规则中检查的用户名索引:

 app : { users: { "some-user-uid": { email: "test@test.com" username: "myname" } }, usernames: { "myname": "some-user-uid" } } 

因此, usernames节点将用户usernames映射到uid。 它本质上读作“username’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的建议保存用户名,但在保存用户名时,请使用Firebase中的runTransaction函数以确保不使用用户名。 Firebase保证此function是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: {  { 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]; }