Firebase android:使用户名唯一

Flo*_*oGz 31 android firebase firebase-security firebase-authentication

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

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

app : {
    users: {
       "some-user-uid": {
            email: "test@test.com"
            username: "myname"
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

{
    "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()"}
            }
        }
   }
}
Run Code Online (Sandbox Code Playgroud)

非常感谢您的帮助

Fra*_*len 48

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

app : {
    users: {
       "some-user-uid": {
            email: "test@test.com"
            username: "myname"
       }
    },
    usernames: {
        "myname": "some-user-uid"
    }
}
Run Code Online (Sandbox Code Playgroud)

因此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"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这样可以验证用户尚未声明用户名或当前用户声明用户名.

  • 嗨弗兰克,我认为重要的是要注意你应该把所有支票都转换为`usernames`为小写并存储小写,这样你就不能拥有不同情况的相同用户名.存储在`users/some-user-uid/username`字段中的值可以区分大小写,可以是可读的版本,这应该允许更友好的用户名选择和案例依从性. (4认同)

Viv*_*ven 5

按照Frank的建议保存用户名,但是在保存用户名时,请使用Firebase中的runTransaction函数来确保未使用用户名。Firebase保证此功能是原子操作,因此您可以放心不会发生碰撞

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
        }
    }
});
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

16611 次

最近记录:

8 年,8 月 前