我需要使用以下值更新集合:
{
"email" : "x@gmail.com",
"fullName" : "Mehr",
"locations" : ["sss","dsds","adsdsd"]
}
位置必须是一个数组。在firebase中,我该怎么做...而且还应该检查是否重复。
我确实是这样的:
const locations=[]
locations.push(id)
firebase.database().ref(`/users/ + ${userId}`).push({ locations })
答案 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;
现在有两个选择:
有关更多信息,请参见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方法用于同时更新多个路径。这在这种情况下会很有帮助,但是如果您在循环中使用推入,则必须等待所有推入返回承诺。在更新方法中,它将立即处理所有的承诺和回报。无论是成功还是失败。