【问题标题】:Proper way to store values array-like in Firebase在 Firebase 中存储值数组的正确方法
【发布时间】:2020-01-08 07:56:49
【问题描述】:

我有这首歌的名字,我正在为它保存评分。 它看起来像下面的图片,因为我使用push() 来存储每个新评级。

但我想看到的是,ratings 作为一个数组 对象,每个都包含如下内容:

voter: {
    ip: "1.1.1.1",
    stars: 3,
}

所以rating 键最终会是这样的:

rating: [{ip: "1.1.1.1", stars: 3}, ...]

然后我可以为每个 IP 地址启用一票。我找不到的东西 Firebase docs,是如何添加到现有密钥,在这种情况下 rating(但它会是 [list, like]) - a 新的hash 和上面的一样。 因为push() 自动创建hash-key 值,我想追加 到现有的密钥。

编辑: 我知道这一事实,Firebase 本身并不存储数组,但在这种情况下,这并不重要,这只是我希望看到我的数据的方式。

【问题讨论】:

    标签: arrays firebase


    【解决方案1】:

    您当前正在使用push 添加新子节点,这会自动为新节点生成一个“保证”在多个客户端中唯一的名称。

    ref.push({ ip: userIP, stars: userStars });
    

    Firebase 的push 方法是让多个客户端向有序集合添加项目的好方法。如果您想使用数组完成相同的操作,则必须在客户端之间同步数组的长度。 Firebase 的名称生成不需要这样的开销,因此通常首选跨多个客户端保持订单集合。

    但在您的情况下,您似乎不想要一个有序的“仅附加”集合。您似乎认为 IP 地址是每个节点的标识。在这种情况下,我会使用 IP 地址作为节点名称的基础:

    votes
      "1.1.1.1": 3
      "1.2.3.4": 5
      "1.7.4.7": 2
    

    您可以通过以下方式完成此操作:

    ref.child(userIP).set(userStars);
    

    如果你想随后将所有投票读入一个数组,你可以这样做:

    var votes = [];
    votesRef.on('value', function(snapshot) {
        snapshot.forEach(function(vote) {
            votes.push({ ip: vote.key, stars: vote.val() });
        });
        alert('There are '+votes.length+' votes');
    })
    

    【讨论】:

    • 谢谢!我遇到了同样的问题,这对我有用。
    • 我试过这段代码,似乎是vote.key而不是vote.key()。我很乐意编辑帖子,但我需要更改至少 6 个字符!
    • 感谢举报。自从我写了这个答案以来,这确实是 Firebase API 的一个变化。我更新了答案。
    【解决方案2】:

    我想创建一个可重用的函数来添加/保存根节点下的任何对象(即使该对象内的任何级别都有数据数组)。所以我想出了这个。 (我不确定是否符合最佳实践,但它工作得非常顺利)

        SaveWholeData: function(sKey, oVal, bGenKey) {
            bGenKey = bGenKey === undefined ? true: bGenKey;
            var oOriginalProperty = angular.copy(oVal);
            for (var property in oVal) {
                if (oVal.hasOwnProperty(property) && oVal[property] instanceof Array) {
                    console.log(property);
                    oVal[property] = "$|$";
                }
            }
            var sOwnRef = SaveDataByKey(sKey, oVal, bGenKey);
            for (var property in oVal) {
                if (oVal.hasOwnProperty(property) && oVal[property] === "$|$") {
                    oVal[property] = oOriginalProperty[property];
                    var updatedReference = sOwnRef + "/" + property;
                   SaveWholeData(updatedReference, oVal[property], false);
                }
            }
            return true;
        },
        SaveDataByKey: function(sKey, oVal, bGenKey) {
            if (bGenKey) {
                var newPostKey = firebase.database().ref(sKey).push().key;
                oVal.genKey = newPostKey;
                firebase.database().ref(sKey).child(newPostKey).set(oVal);
                return sKey + "/" + newPostKey;
            }else{
                firebase.database().ref(sKey).set(oVal);
                return sKey;
            }
        }
    

    所以要在根users添加新用户,您调用:

    SaveWholeData("users", oUserInfo, true);
    

    更新现有用户

    SaveWholeData("users"+"/"+ oUserInfo.genKey, oUserInfo, true);
    

    【讨论】:

      【解决方案3】:

      从数据库 firebase 获取值后,您可以使用 forEach() 将其存储在另一个数组中,如下所示:

       const arrayPlayers = []
              this.db.database.ref('player').once('value')
                 .then((snapshot)=> {               
                      snapshot.forEach((childSnapShot:any)=>{
                          arrayPlayers.push(childSnapShot.val())
                      })
                      //Here your array will be withut the node, like so:
                      //[3,5,1,...]
                      //Now sort array with JS
                      const sortPlayers = arrayPlayers.sort((a:any, b:any)=> b.score - a.score)
                      console.log(sortPlayers);
      
                  })
      

      【讨论】:

        猜你喜欢
        • 2016-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-11
        相关资源
        最近更新 更多