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

时间:2018-03-20 11:10:26

标签: java android firebase firebase-realtime-database google-cloud-firestore

我有两个活动,我正在分别从这两个活动向Firestore添加数据。但是,每当我向Firestore添加第二个活动数据时,它都会覆盖第一个活动数据。我在以下两个活动中使用了以下代码:

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

如何停止覆盖?我想将两个活动数据保存在同一个user_id

5 个答案:

答案 0 :(得分:5)

有两种方法可以实现这一目标。第一个是使用Map

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

如您所见,我使用了update()方法而不是set()方法。

第二种方法是使用模型类的对象:

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

正如您所看到的,我使用了set()方法,但我已将其作为第二个参数SetOptions.mergeFields("yourProperty")传递,这意味着我们仅对特定字段进行更新。

答案 1 :(得分:4)

我建议您再添加一个文档或集合,以便为单个用户存储更多的数据值。
您可以为这两个活动创建文档参考:

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

或者你可以为它创建一个子集合:

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

有关分层数据的更多信息there

答案 2 :(得分:1)

根据文档,您可以使用第二个参数{merge:true},根据我的经验,问题通常在于您尝试使用相同的密钥存储不同的数据。

即使使用{merge: true},也会始终使用您传入的值更新当前密钥。

合并:true仅在密钥不存在时才有效。我相信文档中的每个键都必须是唯一的。

为了测试它尝试传递(保持{merge: true}作为第二个参数)数据与不同的键,它将合并到现有。

答案 3 :(得分:0)

如果您知道用户文档已经存在于firestore中,那么您应该使用

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

如果您不知道文档是否存在,那么您可以使用

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

这会执行数据的深度合并

或者您也可以使用子集合

来完成

答案 4 :(得分:0)

请尝试直接更新

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

仅字段评级会更改,其余字段将保持不变。

假设您有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
    });
});