如何在Firebase中防止两次更新

时间:2018-08-11 14:48:32

标签: reactjs firebase firebase-realtime-database

我有一个非常简单的论坛,其中包含React和firebase,目前每个人都可以在帖子上投票,但是问​​题是您可以多次单击“喜欢”和“不喜欢”按钮。

如何防止这种情况?我正在尝试对location.storage进行操作,但不确定如何跟踪每条帖子。

class App extends React.Component {
  downvotePost(key, text, vote) {
    // alert(id);
    // CommentsRef.child(id).transaction(function(Comments) {
    //   if (Comments) {
    //     Comments.vote++;
    //   }
    //  console.log('cc',Comments);
    //   return Comments;
    // });

    vote--;
    CommentsRef.child(key).update({ vote: vote });
  }

  upvotePost(key, text, vote) {
    // alert(id);
    // CommentsRef.child(id).transaction(function(Comments) {
    //   if (Comments) {
    //     Comments.vote++;
    //   }
    //  console.log('cc',Comments);
    //   return Comments;
    // });

    vote++;
    CommentsRef.child(key).update({ vote: vote });
  }

  componentWillMount() {
    const { dispatch, match } = this.props;
    dispatch(getsinglechamp(this.props.id));
    console.log(this.props);
  }

  componentDidMount() {
    const hasVisitedBefore = localStorage.getItem("hasVisitedBefore");

    // Check if the user has visited the site (component) before.
    if (!hasVisitedBefore) {
      // If not, set the component state (or dispatch an action if you need)
      // Also set the localStorage so it's globally accessible.
      this.setState({ hasVisitedBefore: false });
      localStorage.setItem("hasVisitedBefore", true);
    }
  }

  render() {
    const { dispatch, loading } = this.props;
    const { comments, ChampsLoading } = this.state;
    const orderedchamps = comments;

    let commentList;

    if (ChampsLoading) {
      commentList = <div className="TaskList-empty">Loading...</div>;
    } else if (comments.length) {
      commentList = (
        <ul className="TaskList">
          {comments.map(comment => (
            <div className="row">
              <div className="col-lg-6">
                <br /> <br /> <br />
                <div className="cs-counter-tips-list">
                  <div className="cs-counter-tip">
                    {this.state.hasVisitedBefore
                      ? "you can vote on this post"
                      : "disable button if user voted"}
                    <button
                      id="f"
                      onClick={() =>
                        this.upvotePost(comment.key, comment.text, comment.vote)
                      }
                    >
                      <Icon icon={chevronUp} />
                    </button>
                    <div id="col" className="col-lg-6">
                      {comment.vote}
                    </div>
                    <button
                      id="f"
                      onClick={() =>
                        this.downvotePost(
                          comment.key,
                          comment.text,
                          comment.vote
                        )
                      }
                    >
                      <Icon icon={chevronDown} />
                    </button>
                    <div>
                      <p className="cs-counter-tip-text">{comment.text} </p>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          ))}
        </ul>
      );
    }
    return (
      <div className="container">
        <h1>Counter Tips</h1>

        <div className="brace"> </div>

        <p> {commentList} </p>
      </div>
    );
  }
}

1 个答案:

答案 0 :(得分:1)

这里缺少很多东西:

  1. 您将需要跟踪谁已经投票。通常使用以下列表来完成此操作:

    posts
      post1id
        voteCount: 2
        voters
          voter1uid: true
          voter2uid: true
      post2id
        voteCount: 2
        voters
          voter1uid: true
          voter3uid: true
    
  2. 您将需要使用一笔交易来更新投票,并且投票者一口气。通过Firebase数据库交易,您可以安全地根据voteCount的当前值来确定新值,该事件是在多个人同时投票的情况下发生的。

  3. 您将需要编写安全规则(由Firebase数据库服务器实施),以确保代码只能以与{{ 1}}。有关更多信息,请参见我的回答:Is the way the Firebase database quickstart handles counts secure?