简体   繁体   English

如何正确更新 firebase-realtime-database 中的对象?

[英]How to update an object in firebase-realtime-database correctly?

at the moment users are stored in my real-time firebase database.目前用户存储在我的实时 firebase 数据库中。

The User-Class contains:用户类包含:

private String uid;
private UserPermissions userPermissions;
private List<Item> items;

The list items is empty by default, which results into the following database structure:默认情况下,列表为空,这导致以下数据库结构:

在此处输入图像描述

A Button is used to add an item to the list of the current user. Button 用于将项目添加到当前用户的列表中。

Currently I'm trying to update the database by the whole user object, like this:目前我正在尝试通过整个用户对象更新数据库,如下所示:

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

Which results into the following:结果如下:

在此处输入图像描述

The hierarchy is broken.层次结构被打破了。

Is there any other possiblity to update the lists items of an existing user without setting the whole user object to the database?在不将整个用户对象设置到数据库的情况下,是否还有其他可能更新现有用户的列表项? If not, how would it be possible to prevent this problem?如果没有,怎么可能防止这个问题?

How would it be possible to update the user similiar to the MySQL syntax with a where condition?如何使用 where 条件更新类似于 MySQL 语法的用户?

UPDATE `ingredients` SET `ingredient` = `new_value' WHERE `uid` = `PClW...`;

Thanks for the help in advance!我在这里先向您的帮助表示感谢!

Its probably helpful to keep in mind that in the Firebase RTDB data model, a given node contains all of its children, always, in their entirety.记住在 Firebase RTDB 数据模型中,给定节点始终完整地包含其所有子节点可能会有所帮助。 There isn't really a concept of tables, or even "collections" that you might find in Firestore.没有真正的表格概念,甚至您在 Firestore 中可能找不到的“集合”。

This is important because you are calling setValue() which sets the reference that you call it for to the exact value passed -- it performs a full replacement .这很重要,因为您正在调用setValue() ,它将您调用它的引用设置为传递的确切值——它执行完全替换 In the words of the documentation :文档的话来说:

Using setValue() in this way overwrites data at the specified location, including any child nodes.以这种方式使用 setValue() 会覆盖指定位置的数据,包括任何子节点。

In this case, the reference you are using is pointing at the users node, not at the node for the current user.在这种情况下,您使用的引用指向users节点,而不是当前用户的节点。 So, what you see is that the entire users node is replaced with the value for a single user.因此,您看到的是整个users节点被替换为单个用户的值。

You have two options.你有两个选择。

The first and most straightforward is to get a reference to the node of the specific user you want to update call setValue on that:第一个也是最直接的是获取对要更新的特定用户的节点的引用调用setValue

ref = FirebaseDatabase.getInstance().getReference()
        .child("users").child(uid);

Note that the uid here is actually the key for the node you are trying to update (in this case -LuxronyXRi8s85SBvVf ).请注意,这里的uid实际上是您要更新的节点的密钥(在本例中-LuxronyXRi8s85SBvVf )。 It is not the value of the uid child of that node.不是该节点的 uid 子节点的值。 If you need to find the key because you do not know it, you will need to either iterate through all the children of the users node yourself until you find it or try to find it via a filter query .如果您因为不知道密钥而需要查找它,则需要自己遍历users节点的所有子节点直到找到它,或者尝试通过过滤器查询找到它。

Of course, there is no guarantee (at least not any that Firebase RTDB provides) that only one child node has that particular uid value.当然,不能保证(至少 Firebase RTDB 不能保证)只有一个子节点具有特定的uid值。

Further, if you just want to update one field below the user node, then just get a reference to that instead (again, the uid here refers to the key of the node you want to update):此外,如果您只想更新用户节点下的一个字段,那么只需获取对该字段的引用(同样,这里的 uid 指的是您要更新的节点的):

ref = FirebaseDatabase.getInstance().getReference()
        .child("users").child(uid).child("userPermissions");

Alternatively, if you want to write to multiple children of a node, while leaving the other child nodes in place, you can use updateChildren() .或者,如果您想写入一个节点的多个子节点,同时保留其他子节点,您可以使用updateChildren() See documentation here and the reference here .请参阅此处的文档和此处参考 This can take a map of child paths to values to update to, but is likely more complicated than you need in this case since you appear to be trying to update exactly one user, in its entirety.这可以将子路径映射到要更新的值,但在这种情况下可能比您需要的更复杂,因为您似乎正在尝试完全更新一个用户。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM