首页 > 解决方案 > 检查firestore数组中是否存在元素的最佳方法是什么,如果存在,则运行一个函数,如果不添加它?

问题描述

我正在开发一个“喜欢”按钮,目前每次单击喜欢按钮时喜欢的次数都会增加 1。但是,我想让它更加健壮和动态,如果登录的用户已经喜欢了一个帖子,那么我希望他们的“喜欢”消失,比如 Facebook、Reddit(upvote)等。

目前我正在做的是跟踪喜欢的数量以及谁喜欢了一个帖子。结构如下所示:

post: {
  likes: 3,
  likedBy: ['userA', 'userB', 'userC']
}

所以我想要发生的是:当点击喜欢按钮时,我想搜索 likeBy 属性以查看登录用户是否已经喜欢该帖子,然后将喜欢的值增加 1,并将它们添加到数组中,或将喜欢减 1 并将它们从数组中删除。

我很难弄清楚如何使用处理与 Firestore 交互的 React 操作来编写此逻辑。

这是我到目前为止所写的:

export const newLike = (post) => {
  return (dispatch, getState, {getFirebase, getFirestore})  => {
    const firestore = getFirestore();
    const signedInUser = getState().firebase.auth;
    console.log(signedInUser)
    firestore.collection('posts').doc(post.id).update({
      likes: (post.likes + 1),
      likedBy: firestore.FieldValue.arrayUnion(signedInUser)
    }).then(()=> {
      dispatch({type: types.NEW_LIKE, post});
    }).catch((err) => {
      dispatch({ type: types.NEW_LIKE_ERROR, err});
    });
  };
};

标签: reactjsgoogle-cloud-firestore

解决方案


在您的数据结构中,您不需要保留likes,因为您可以从 likeBy 获得它。我不熟悉firestore api,但下面的逻辑应该做你想做的事,你只需要从firestore获取/设置日期

  return (dispatch, getState, {getFirebase, getFirestore})  => {
    const signedInUser = getState().firebase.auth;
    const posts = ...// get current state of post, with likedBy field. Also, I assume here, that likedBy is always an array, with data or empty
    let updatedLikedBy;
    if(posts.likedBy.indexOf(signedInUser) ===-1){ //assuming that signedInUser is a string
      updatedLikedBy = [...post.likedBy, signedInUser]
    } else {
      updatedLikedBy = post.likedBy.filter(item=>item!==signedInUser)
    }

    const updatedPost = {likedBy: updatedLikedBy} // now you can send this to firestore, and fire actions after success or fail.
  };
};

现在你likes只需要做posts.likedBy.length


推荐阅读