java - 如何正确更新 firebase-realtime-database 中的对象?
问题描述
目前,用户存储在我的实时 firebase 数据库中。
用户类包含:
private String uid;
private UserPermissions userPermissions;
private List<Item> items;
列表项默认为空,这导致以下数据库结构:
Button 用于将项目添加到当前用户的列表中。
目前我正在尝试通过整个用户对象更新数据库,如下所示:
ref = FirebaseDatabase.getInstance().getReference().child("users");
[...]
Button dialogButton = (Button) dialog.findViewById(R.id.addItem);
dialogButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ref.setValue(user);
dialog.dismiss();
}
});
结果如下:
层次结构被打破。
是否有任何其他可能性来更新现有用户的列表项而不将整个用户对象设置为数据库?如果没有,如何防止这个问题?
如何使用 where 条件更新类似于 MySQL 语法的用户?
UPDATE `ingredients` SET `ingredient` = `new_value' WHERE `uid` = `PClW...`;
我在这里先向您的帮助表示感谢!
解决方案
请记住,在 Firebase RTDB 数据模型中,给定节点始终包含其所有子节点,这可能会有所帮助。Firestore 中并没有表的概念,甚至没有“集合”的概念。
这很重要,因为您正在调用setValue()
它将您调用它的引用设置为传递的确切值 - 它执行完全替换。用文档的话来说:
以这种方式使用 setValue() 会覆盖指定位置的数据,包括任何子节点。
在这种情况下,您使用的引用指向users
节点,而不是当前用户的节点。因此,您看到的是整个users
节点被替换为单个用户的值。
你有两个选择。
第一个也是最直接的方法是获取对要更新调用的特定用户的节点的引用setValue
:
ref = FirebaseDatabase.getInstance().getReference()
.child("users").child(uid);
请注意,uid
这里实际上是您尝试更新的节点的键-LuxronyXRi8s85SBvVf
(在这种情况下)。它不是该节点的 uid 子节点的值。如果您因为不知道密钥而需要找到它,您将需要自己遍历节点的所有子users
节点,直到找到它,或者尝试通过过滤器查询找到它。
当然,不能保证(至少 Firebase RTDB 不提供任何保证)只有一个子节点具有该特定uid
值。
此外,如果您只想更新用户节点下方的一个字段,则只需获取对该字段的引用(同样,这里的 uid 是指您要更新的节点的键):
ref = FirebaseDatabase.getInstance().getReference()
.child("users").child(uid).child("userPermissions");
或者,如果您想写入一个节点的多个子节点,同时保留其他子节点,您可以使用updateChildren()
. 请参阅此处的文档和此处的参考。这可以将子路径映射到要更新的值,但在这种情况下可能比您需要的更复杂,因为您似乎正在尝试完全更新一个用户。
推荐阅读
- javascript - 无法使用正则表达式在模式之间提取字符串
- python - 在熊猫数据框中读取具有可变列的文本文件
- assembly - RiscV 跳转 (j, jal) 到错误地址(偏移量 2)
- ios - 为什么动画中的图片不能显示?
- javascript - 在我的网站上进行地理定位的解决方案
- javascript - 如何防止 runtime.lastError 错误消息出现在控制台中?
- swift - 如何转换字符串中的任何数字Amount
- reactjs - 在 react 组件中保持与 ui 相关的强状态是一种不好的做法吗?
- php - 如何在运行时更改 Tymon 的 JWT Auth 包中的 jwt 密码以对不同主机(子域)的令牌进行编码
- php - 使用自定义键推送到会话数组