【问题标题】:Firebase: check if username already existsFirebase:检查用户名是否已经存在
【发布时间】:2016-09-20 19:58:53
【问题描述】:

如何确保用户名(由用户通过EditText 字段选择)是唯一的?我目前正在使用实时数据库:

FirebaseAuth auth = FirebaseAuth.getInstance();
FirebaseUser user = auth.getCurrentUser();
mDatabase = FirebaseDatabase.getInstance();
User mUser = new User(user.getUid().toString(), username);
DatabaseReference allUsersRef = mDatabase.getReference("AllUsers");
allUsersRef.child(user.getUid().toString()).setValue(mUser);

username = 用户选择的用户名;User = 仅包含 UID 和用户名的对象)

这会产生以下结构:

MyApp
 |
 ---AllUsers
     |
     ---THE_USERS_UID
          |
          |---username: "THE_USERS_USERNAME"
          |
          |---uid: "THE_USERS_UID"

那么,如果其他人打开我的应用并且必须选择用户名,我该如何“防止”他选择已经被其他人使用的用户名?

干杯!

【问题讨论】:

  • 您可以使用 dataSnapshot.exists() 或 dataSnapshot.hasChild() 方法。
  • Calam 的答案有重要的部分,即您需要使用规则来保护它。另见this classic answer,可能还有很多these

标签: android firebase firebase-realtime-database


【解决方案1】:

您可以在位置 /usernames 创建另一个分支,其中包含具有已使用用户名键的子级和声明它的用户的 $uid 的父级,例如

{
    "users": {
        "$uid": {
            "username": {
                "callam": true
            }
        }
    },
    "usernames": {
        "callam": {
            "$uid": true
        }
    }
}

您现在可以在users/$uid/username/$username 创建一个验证规则,该规则仅在用户的$uid/usernames/$username/$uid 声明了$username 时才允许写入。

"users": {
    "$uid": {
        "username": {
            ...,
            "$username": {
                ".validate": "root.child('usernames/' + $username).hasChild($uid)"
            }
        }
    }
}

并且您可以制定另一条规则,仅允许您在 /usernames/$username 处声明用户名,前提是该位置还没有值。

"usernames": {
    ...,
    "$username": {
        "$uid": {
            ".validate": "auth.uid == $uid && !data.exists()"
        }
    }
}

交替

数据库

{
    "usernames": {
        "callam": "$uid"
    },
    "users": {
        "$uid": {
            "username": "callam"
        }
    }
}

规则

{
    "usernames": {
        "$username": {
            ".validate": "auth.uid == newData.val() && !data.exists()"
        }
    },
    "users": {
        "$uid": {
            "username": {
                ".validate": "auth.uid == $uid && root.child('usernames/'+newData.val()).val() == $uid"
            }
        }
    }
}

【讨论】:

  • 最后一条规则中的` ".validate": "auth.uid == newData.val() && !data.exists()"` 确实是解决这个问题的关键。它可以防止任何人覆盖现有的“已声明”用户名,但仍允许所有者将其删除。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-28
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
  • 2015-05-05
相关资源
最近更新 更多