使用Firebase中的数组更新集合

时间:2018-08-16 04:40:04

标签: firebase firebase-realtime-database

我需要使用以下值更新集合:

{
  "email" : "x@gmail.com",
  "fullName" : "Mehr",
  "locations" : ["sss","dsds","adsdsd"]
 }

位置必须是一个数组。在firebase中,我该怎么做...而且还应该检查是否重复。

我确实是这样的:

 const locations=[]
 locations.push(id)

firebase.database().ref(`/users/ + ${userId}`).push({ locations })

3 个答案:

答案 0 :(得分:2)

由于需要检查重复项,因此需要首先读取数组的值,然后更新它。在Firebase实时数据库中,可以通过transaction完成该组合。您可以在locations节点本身上运行事务:

var locationsRef = firebase.database().ref(`/users/${userId}/locations`);
var newLocation = "xyz";

locationsRef.transaction(function(locations) {
  if (locations) {
    if (locations.indexOf(newLocation) === -1) {
      locations.push(newLocation);
    }
  }
  return locations;
});

如您所见,这将加载位置,确保一次显示新位置,然后将其写回数据库。


请注意,Firebase建议将数组用于类似集合这样的数据结构。考虑使用更直接的数学集到JavaScript的映射:

"locations" : {
  "sss": true,
  "dsds": true,
  "adsdsd": true
}

此结构的一个优点是,添加新值是幂等运算。假设我们有一个位置“ sss”。我们通过以下方式将其添加到该位置:

locations["sss"] = true;

现在有两个选择:

  1. “ sss”尚未在节点中,在这种情况下,此操作会将其添加。
  2. “ sss”已在节点中,在这种情况下,此操作不执行任何操作。

有关更多信息,请参见best practices for arrays in Firebase

答案 1 :(得分:0)

您可以简单地将这些项目推入循环中

if(locations.length > 0) {
    var ref = firebase.database().ref(`/users/ + ${userId}`).child('locations');
    for(i=0; i < locations.length; i++) {
        ref.push(locations[i]);
    }
}

这还会为项目创建唯一键,而不是数字索引(该数字可能会发生变化)。

答案 2 :(得分:0)

您可以使用 update 而不是 push 方法。这对您来说会容易得多。尝试如下

var locationsObj={};
if(locations.length > 0) {
    for(i=0; i < locations.length; i++) {
       var key= firebase.database().ref(`/users/ + ${userId}`).child('locations').push().key;
       locationsObj[`/users/ + ${userId}` +'/locations/' + key] =locations[i];
    }
    firebase.database().ref().update(locationsObj).then(function(){// which return the promise.
        console.log("successfully updated");
    })  
}

注意:update方法用于同时更新多个路径。这在这种情况下会很有帮助,但是如果您在循环中使用推入,则必须等待所有推入返回承诺。在更新方法中,它将立即处理所有的承诺和回报。无论是成功还是失败。