【问题标题】:Saving data to child in Firebase将数据保存到 Firebase 中的孩子
【发布时间】:2018-07-07 03:40:33
【问题描述】:

我有一个小型应用程序,用户可以在其中根据球员最近在各种运动中的表现对他们进行投票或反对。

当当前点击upvote按钮时,选民的UID(通过谷歌登录)应该被推送到被投票的相应玩家的数据库中。像这样:

但是,它目前正在这样做:

这是执行 Firebase 工作的代码。我相信这是我错的这些行之一。

this.database.child(playerId).transaction

ref = firebase.database().ref('players/voters');

代码:

this.database = firebase.database().ref().child('players');

upvotePlayer(playerId) {
this.state.user ?
  this.database.child(playerId).transaction(function (player) {
    if (player) {
      console.log("UID: " + uid)
      var ref = firebase.database().ref('players/voters');
      ref.child(uid).set(1);
    }
    return player;
  })
  :
  console.log("Must be logged in to vote.")

  }

【问题讨论】:

  • 好吧,playerid是uid还是pushid?
  • 抱歉,我应该更具体一些。 playerId 是在图像示例中为 firebase -L3vkv.. 等中的每个运动员推送的唯一 ID。登录选民的 UID 就是 uid

标签: firebase firebase-realtime-database


【解决方案1】:

问题是因为这个:

 var ref = firebase.database().ref('players/voters');

它是在players 节点下添加voters,而不是在push id 节点下。

所以你必须从数据库中检索 pushid,然后这样做:

  var ref=firebase.database().ref().child('players').child(playerId).child('voters');

因此选民将成为pushid 孩子之一。

对于未来的观众:

最好使用事务,因为:

如果多个用户同时对同一个帖子进行投票或客户端的数据过时,则使用事务可以防止投票计数不正确

【讨论】:

  • 这似乎是对的。问题是,当我单击 upvote 并查看 firebase 数据库时,它显示选民出现,但变成红色并消失。数据由于某种原因没有保留
  • 你要添加这个ref.child(uid).set(1);吗?显示红色后是否还有其他数据?
  • 是的,就是添加了那行。没有那行,数据库中不会出现任何内容。没有其他数据出现,只有选民。
  • 是的,你必须写那行。试试这个ref.child(uid).update(1); 而不是这个ref.child(uid).set(1); @idlehand
  • 错误:Reference.update 失败:第一个参数必须是包含要替换的子对象的对象。 — > 137 | ref.child(uid).update(1);
【解决方案2】:

您将投票存储在此路径 players/voters 中,而它应该存储在此路径 players/$playerId/voters

看看这个

this.database = firebase.database().ref().child('players');

upvotePlayer(playerId) {
    this.state.user ?
        this.database.child(playerId).transaction(function (player) {
            if (player) {
                console.log("UID: " + uid)
                var ref = firebase.database().ref('players/' + playerId + '/voters');
                ref.child(uid).set(1);
            }
            return player;
        })
        :
        console.log("Must be logged in to vote.")
}

transaction 方法有 transactionUpdate 函数作为参数,它应该返回新值而你没有返回任何值,我认为更好的解决方案是不使用事务

编辑:没有事务的解决方案

upvotePlayer(playerId) 
{
    if(this.state.user)
    {
        let ref = firebase.database().ref('players/' + playerId + '/voters');
        ref.child(uid).set(1);
    }
    else
    {
        console.log("Must be logged in to vote.")
    }
}

【讨论】:

  • 'voters' 成功地短暂显示它应该在哪里,但在 Firebase 中变成红色并消失,其他解决方案也是如此。任何想法为什么?
  • 因为你使用事务,如果我是你的情况,我不会使用事务,检查编辑
  • 谢谢 — 我没有完全了解事务函数的性质。感谢您的帮助
【解决方案3】:

实际上,您正在将价值推送到带有玩家 ID 的付款人节点。您已将数据推送到玩家 ID voters 的子节点。试试这个代码:-

this.database = firebase.database().ref().child('players');

upvotePlayer(playerId) {
this.state.user ?
  this.database.child(playerId).transaction(function (player) {
    if (player) {
      console.log("UID: " + uid)
      player.ref.child(voters).push(uid);
    }
    return player;
  })
  console.log("Must be logged in to vote.")

  }

问题是您实际上是在引用players 节点并在名为voters 的playerid 同一级别创建新节点。下面的行只是在playerid 的同一级别创建一个新节点voters

  var ref = firebase.database().ref('players/voters');
  ref.child(uid).set(1);

如您所见,players 根节点中没有名为 voters 的节点。但是您正在设置该值,因此它是使用 set() 函数使用新数据创建的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多