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

非常感谢您的帮助

原文由 FloGz 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 355
2 个回答

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

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

因此 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"
    }
  }
}

这验证了该用户名尚未被任何人声明,或者它已被当前用户声明。

原文由 Frank van Puffelen 发布,翻译遵循 CC BY-SA 3.0 许可协议

按照 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
        }
    }
});

原文由 Viven 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题