gpt4 book ai didi

android - Firebase 在不读取快照或尝试写入(对于唯一用户名)的情况下检查值是否存在?

转载 作者:行者123 更新时间:2023-11-30 00:45:05 25 4
gpt4 key购买 nike

我已经在这个问题上停留了好几个小时了,所以非常感谢您的帮助。尝试使用 Firebase 制作 Android 应用程序以进行用户身份验证(简单的登录电子邮件和密码)以及唯一用户名。我将我的注册屏幕字段布置在一个屏幕上,例如:

"Enter Username"
"Enter Email Address"
"Enter Password"

我很困惑如何查询数据库以检查用户名是否存在没有读取数据库快照并且没有尝试将用户名写入数据库(因为这是在用户处于 auth == null 状态时发生的,所以在用户创建帐户之前的注册页面上,我想通知用户他的用户名是否已被使用)。

我的意思是,这感觉应该非常简单,只是使用字符串对 Firebase 进行简单查询,然后让 Firebase 返回 TrueFalse,但是之后几个小时的谷歌搜索我一无所获。

我不想使用快照来执行此操作的原因是因为我不想通过将“read”设置为 true 来向公众公开我所有的用户名和他们的 UID(我遵循了本指南,因此我的安全规则就是这样设置的,还有我的数据库结构 Firebase android : make username unique )。

这是我的规则,它们目前有效(我不喜欢将读取设置为 True 的事实,这就是我问这个问题的原因):

{
"rules": {
"usernames": {
".read": true,
"$username": {
".write": "auth !== null && !data.exists()"
}
},
"users": {
"$uid": {
".write": "auth !== null && auth.uid === $uid && !data.exists()",
".read": "auth !== null && auth.provider === 'password' && auth.uid === $uid",
"username": {
".validate": "(!root.child('users').child(newData.val()).exists() || root.child('usernames').child(newData.val()).val() == $uid)"
}
}
}
}
}

这是我的数据:

{
"usernames" : {
"abcd" : "some-user-uid"
},
"users" : {
"\"some-user-uid\"" : {
"username" : "abcd"
}
}
}

谢谢!

最佳答案

不幸的是,如果不通过 SDK 实际下载数据,则无法测试数据是否存在。数据结构在这里将至高无上(推荐阅读:NoSQL Data Structures,当优化和规模至关重要时,您不应该害怕 denormalize 一些数据。

一般来说,您应该保持数据结构良好,以便有效负载较小并获取它。如果你正在获取一些不能等待字节被获取的东西(例如游戏,非常大的数据集上奇怪的一次性管理操作等),那么这里有一些合理的方法来模拟这个:

通过 REST API 获取 key 列表

使用属性 shallow=true在对 REST API 的调用中将阻止加载大型数据集并仅返回该路径上的键。请注意,如果您存储一百万条记录,它们仍然必须加载到服务器的内存中(慢)并且您仍然必须获取一百万个字符串(昂贵)。

因此,在不实际下载数据的情况下检查路径中数据是否存在的一种方法是调用该路径,例如 https://<YOUR-FIREBASE-APP>.firebaseio.com/foo.json?shallow=true , 并检查是否返回任何 key 。

创建一个您可以查询的非规范化索引

如果您真的需要从 Firebase 数据库中挤出一些额外的性能和速度(提示:除非您每分钟运行数百万个查询并且可能仅用于游戏逻辑和类似查询,否则您不需要这个),您可以双重写入您的记录(即非规范化),如下所示:

/foo/data/$id/... data goes here...
/foo/index/$id/true (just a boolean value)

要双重写入,您将使用更新命令,以及类似于以下内容的写入(Android SDK 示例):

public void addRecord(Map<String, Object> data) {
DatabaseReference db = FirebaseDatabase.getInstance().getReference();

// create a new record id (a key)
String key = db.child("foo").push().getKey();

// construct the update map
Map<String, Object> dualUpdates = new HashMap<>();
dualUpdates.put("/data/" + key, /* data here */);
dualUpdates.put("/index/" + key, true);

// save the new record and the index at the same time
db.child("foo").updateChildren(dualUpdates);
}

现在要确定一条记录是否存在,无需实际下载数据,我可以简单地查询 /foo/index/$id并尝试 DataSnapshot.exists() ,以下载单个 bool 值为代价。

关于android - Firebase 在不读取快照或尝试写入(对于唯一用户名)的情况下检查值是否存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41947218/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com