更新firebase而不重复

时间:2016-01-22 10:41:31

标签: javascript firebase

我认为firebase与数据结构混淆。

我的数据结构如下

myApp--> news 

          --> K8ZqRIzrX6L3q-HjO8V --> title : "value title1"
                                  --> body : "value body1"
                                  --> ....

          --> K8ZqRJ1tI7onmoVX8G4 --> title : "value title2"
                                  --> body : "value body2"
                                  --> ....

现在我想将更多数据推送到Firebase。我有像贝娄这样的对象:

 [{title: "value title2", body: "value body2", ...},{title: "value title3", body: "value body3", ...}]

我的对象有重复。当我推送到Firebase时,它会使用新的自动生成密钥添加全新对象。相反,我希望firebase只更新新值并避免重复。

编辑: 我使用了myFirebaseRef.push(),示例代码在这里,

                objNews.forEach(function(news){
                    myFirebaseRef.push(news,function(){
                    $('.result').append('<li><strong>' + news.title + '</strong></li>');
                    });   
                }); 

objNews有新数据以及firebase已有的数据。我想要实现的只是从ObjNews中推送新数据并避免firebase已经拥有的数据。但是我的代码将Object中的所有数据推送到firebase,从而导致重复。

1 个答案:

答案 0 :(得分:2)

如果我理解正确,你有一个包含新闻文章的JavaScript数组:

[
  {title: "value title2", body: "value body2", ...},
  {title: "value title3", body: "value body3", ...}
]

您希望将此阵列发送到Firebase,然后能够更新阵列中的值并将更新发送到Firebase。

这是反模式,不要这样做!

诀窍在于知道哪个数组索引映射到Firebase中的哪个push-id。

var keysByIndex = {};
objNews.forEach(function(news, index){
    var newRef = myFirebaseRef.push(news);
    keysByIndex[index] = newRef.key();
});

现在您可以检查对象是否已存储在Firebase中,如果已存储,请更新它:

var keysByIndex = {};
objNews.forEach(function(news, index){
    if (keysByIndex[index]) {
        var newRef = myFirebaseRef.push(news);
        keysByIndex[index] = newRef.key();
    }
    else {
        myFirebaseRef.child(keysByIndex[index]).update(news);
    }
});

这种方法存在着令人难以置信的陷阱。

这是处理此方案的更好方法。

高度建议您采取相反的方法:在Firebase中完成所有写入操作,然后从那里收听数据数组。这有时被称为单向流(因为所有数据都在单个连续循环中流动)或command-query segregation principle

它的工作原理如下:

your app                        Firebase
                                  +-+
 -------- send write command -->  | |
 +-+                              | |
 |s|                              |s|
 |t|                              |t|
 |a|                              |a|
 |t|  <-- listen for changes ---  |t|
 |e|                              |e|
 +-+                              | |
                                  +-+

在这种情况下,本地应用程序状态(您方案中的objNews)来自于收听Firebase。所有更改都写入Firebase,而不是写入本地数组。

如何使用它的一小部分。我只是创建/更新DOM元素,因为那是你的代码也在做的事情:

myFirebaseRef.on('child_added', function(snapshot) {
  // a news article was added, add it to the HTML
  var key = snapshot.key();
  var news = snapshot.val();
  $('.result').append('<li id="'+key+'"><strong>' + news.title + '</strong></li>');
})
myFirebaseRef.on('child_changed', function(snapshot) {
  // a news article was changed, update the HTML for it 
  var key = snapshot.key();
  var news = snapshot.val();
  $('#'+key).html('<li id="'+key+'"><strong>' + news.title + '</strong></li>');
})
myFirebaseRef.on('child_removed', function(snapshot) {
  // a news article was remove, remove the HTML for it 
  var key = snapshot.key();
  var element = document.getElementById(key);
  element.parentNode.removeChild(element);
})

我的jQuery有点生疏,因此可能会出现一些语法错误。