简体   繁体   English

如何在不覆盖的情况下向Firebase Firestore添加值?

[英]How to add values to Firebase Firestore without overwriting?

I have two Activities, I am adding data to Firestore from these two activities individually. 我有两个活动,我正在分别从这两个活动向Firestore添加数据。 But, whenever I add second activity data to Firestore, it is overwriting the first activity data. 但是,每当我向Firestore添加第二个活动数据时,它都会覆盖第一个活动数据。 I used below code in the two activities: 我在以下两个活动中使用了以下代码:

 firebaseFirestore.collection("Users").document(user_id).set(data)

How to stop overwriting? 如何停止覆盖? I want to save both Activities data in the same user_id . 我想将两个活动数据保存在同一个user_id

There are two ways in which you can achieve this. 有两种方法可以实现这一目标。 First one would be to use a Map : 首先是使用Map

Map<String, Object> map = new HashMap<>();
map.put("yourProperty", "yourValue");
firebaseFirestore.collection("Users").document(user_id).update(map);

As you can see, I have used update() method instead of set() method. 如您所见,我使用了update()方法而不是set()方法。

The second approach would be to use an object of your model class like this: 第二种方法是使用模型类的对象,如下所示:

YourModelClass yourModelClass = new YourModelClass();
yourModelClass.setProperty("yourValue");
firebaseFirestore.collection("Users").document(user_id)
    .set(yourModelClass, SetOptions.mergeFields("yourProperty"));

As you can see, I have used the set() method but I have passed as the second argument SetOptions.mergeFields("yourProperty") , which means that we do an update only on a specific field. 正如您所看到的,我使用了set()方法但是我已经作为第二个参数传递了SetOptions.mergeFields("yourProperty") ,这意味着我们只对特定字段进行更新。

I suggest you to add one more document or collection that it will be able to store more just one data values for single user. 我建议你再添加一个文档或集合,它可以为单个用户存储更多的数据值。
You can create a document references for both activities: 您可以为这两个活动创建文档引用:

firebaseFirestore.collection("Users").document(user_id+"/acitivity1").set(data);
//and  
firebaseFirestore.collection("Users").document(user_id+"/acitivity2").set(data);

Or you can create a sub-collection for it: 或者您可以为它创建一个子集合:

firebaseFirestore.collection("Users").document(user_id)
                  .collection("Activities").document("acitivity1").set(data);
//and
firebaseFirestore.collection("Users").document(user_id)
                  .collection("Activities").document("acitivity2").set(data);

More about hierarchical data there . 更多关于那里的分层数据。

If you know that the user document allready exists in firestore then you should use 如果您知道用户文档已经存在于firestore中,那么您应该使用

firebaseFirestore.collection("Users").document(user_id).update(data)

If you don't know if the document exists then you can use 如果您不知道文档是否存在,那么您可以使用

firebaseFirestore.collection("Users").document(user_id).set(data, {merge:true})

This performs a deep merge of the data 这将执行数据的深度合并

Alternatively you can do it by using subcollections 或者,您可以使用子集合来完成

As per the documentation, you could use as a second parameter {merge:true} , in my experience the problem usually is in the fact that you are trying to store different data but with the same key. 根据文档,您可以使用第二个参数{merge:true} ,根据我的经验,问题通常在于您尝试使用相同的密钥存储不同的数据。

Even using {merge: true} will always update the current key with the value you are passing in. 即使使用{merge: true}也将始终使用您传入的值更新当前键。

Merge:true Works only if the key does not exist already. Merge:true仅在密钥不存在时才起作用。 I believe every key in a document must be unique. 我相信文档中的每个键都必须是唯一的。

To test it try to pass(keeping {merge: true} as the second parameter) data with a different key, it will merge to existing. 为了测试它,尝试使用不同的密钥传递(使用{merge: true}作为第二个参数)数据,它将合并到现有数据。

Try this for a direct update 试试这个直接更新

db.collection('cities').doc('restaurants').update({ rating:"3.2" });

Only the field rating is going to change, the rest of the fields will remain the same. 只有现场评级会发生变化,其余字段将保持不变。

Lets say you have 3 fields, and want to change only 2 of them, you can also do this in a different way 假设您有3个字段,并且只想更改其中的2个字段,您也可以以不同的方式执行此操作

// You get the document 'restaurants' and then do the below
db.collection('cities').doc('restaurants').get().then((doc) => {

    // Get the rating field string, parse it to a float, remove 0.4 from it and
    // set it to a tmp variable
    var tmpRating = parseFloat(doc.data()['rating']) - 0.4;

    // Get the array of strings field 'menu' and set it to a tmp variable
    var tmpMenu = doc.data()['menu'];

    // Push 'spaghetti' string to the tmp array of strings( Can also put an
    // adapting string variable instead of a specific string like 'spaghetti'
    tmpMenu.push('spaghetti');

    // Update only the specific fields 'rating' and 'menu' and keep the rest unchanged.
    db.collection('cities').doc(doc.id).update({
        rating: toString(tmpRating), // Don't forget to separate them by commas
        menu: tmpMenu
    });
});

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

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