0

因此,当我用户发表评论时,我正在考虑将他们的个人资料图片 URL 存储在评论对象上,以便我可以轻松访问它,但我认为这行不通,因为如果他们更改个人资料图片或删除它,评论仍将包含他们的旧 URL,我也尝试在 Firestore 中存储对用户的引用,但我不确定是我做错了还是什么,因为我一直遇到错误。

TLDR - 我在问是否有人知道存储和访问特定评论的 URL(将来可能会改变)的方法。

抱歉,如果我没有澄清或解释事情,我对 React 还是很陌生,你可能已经知道了。如果有人有任何问题,我可以尝试更好地解释事情,所以是的,感谢您阅读本文并提前感谢。

import React, { useEffect, useState } from 'react';
import { postComment, deleteComment } from '../../store/actions/commentsActions';
import { connect, useSelector } from 'react-redux';
import { useFirestore } from 'react-redux-firebase';
import { useForm } from 'react-hook-form';
import { toast } from 'react-toastify';
import moment from 'moment';
import { ErrorCircle } from '@styled-icons/boxicons-solid/ErrorCircle';
import { Error } from  '@styled-icons/boxicons-solid/Error';

import { Modal } from '../../helpers/Modal';
import ProfilePlaceHolder from '../../assets/images/user.svg';

import Loading from '../../helpers/Loading';

export const Comments = (props) => {

    const { auth, match, history, commentError } = props;
    const slug = match.params.slug;
    const firestore = useFirestore();
    const profile = useSelector(state => state.firebase.profile);

    const { register, handleSubmit, reset } = useForm();

    const [comments, setComments] = useState([]);
    const [loading, setLoading] = useState(true);

    useEffect(() => {

        const listener = 
        firestore
        .collection('posts')
        .doc(slug)
        .collection('comments')
        .orderBy('createdAt', 'desc')
        .onSnapshot((snapshot) => {
            let _comments = [];
            snapshot.forEach(commentSnapshot => {
                const thisComment = commentSnapshot.data();
                _comments.push({commentData: thisComment, commentId: commentSnapshot.id});
            });
            setComments(_comments);
            setLoading(false);
        }, (error) => {
            console.log(error);
        });

        return () => listener();

    }, [firestore, slug]);

    const postComment = async (formData) => {

        if (auth.isEmpty) {
            toast.error('You are not authenticated ');
            return;
        }
        await props.postComment({formData, slug});
        reset();
    };

    const deleteComment = (commentId, authorId) => {

        const currentUserId = auth.uid;
        const commentUserId = authorId;

        if (!comments) {
            return;
        }

        if (currentUserId !== commentUserId) {
            toast.error('That\'s not your comment')
            return;
        }

        props.deleteComment({commentId, authorId, slug});  
    };

    const back = () => {
        history.goBack();
    };

    if (loading) {
        return <Loading />;
    };



    return (
        <div className='main' style={{ width: '600px', maxWidth: '90%' }}>
            { 
                commentError !== null ? (
                <span className='error-message'>
                    <ErrorCircle size='30' style={{ marginRight: 5 }} />
                    {commentError}
                </span> ) : null
            }
            <div className='long-container' onClick={back} style={{ cursor: 'pointer', height: '50px' }}>
                Commenting on the post: {slug}
            </div>
            <div className='long-container' style={{ padding: '10px 0' }}>
                <div>
                    <img 
                        src={profile.profilePictureURL ?? ProfilePlaceHolder} 
                        alt='Profile' 
                        className='profile-picture' 
                    />
                    <span className='usertag-span'>{auth?.displayName}</span>
                </div>
                <div>
                    <form onSubmit={handleSubmit(postComment)}>
                        <textarea 
                            name='content'
                            rows='3' 
                            disabled={!auth}
                            style={{ margin: '10px 0' }}
                            placeholder='Add to the conversation!'
                            ref={register({ required: true })}
                        /> 
                        <span style={{ width: '90%' }}>
                            <button>Comment</button>
                        </span>
                    </form>
                </div>
            </div>
            {comments.map((comment) =>
            <div key={comment.commentId} className='long-container' style={{ padding: '15px 0' }}>
                <div style={{ height: '30px' }}>
                    <img 
                        src={comment.commentData.authorProfilePicture ?? ProfilePlaceHolder} 
                        alt='Profile' 
                        className='profile-picture'
                    />
                    <div className='commentMetadata' style={{ flexDirection: 'column', alignItems: 'flex-start', justifyItems: 'center' }}>
                        <span className='usertag-span'>{comment.commentData.author}</span>
                        <span>{moment(comment.commentData.createdAt?.toDate()).fromNow()}</span>
                    </div>
                </div>
                <span className='commentText-span'>
                    {comment.commentData.content}
                </span>
                <span className='commentText-span' style={{ justifyContent: 'flex-end' }}>
                    { 
                        auth.uid === comment.commentData.authorId ?
                        (
                            <Modal 
                                buttonActionClassName='delete-button' 
                                visibleButtonClassName='delete-button'
                                modalContentHeaderBackgroundColor='#fa4949'
                                title='Confirm' 
                                modalContent='Are you sure you want to delete this comment?' 
                                emoji={<Error size='30' color='#f53d3d' style={{ marginRight: 10 }} />}
                                buttonActionName='Delete'
                                buttonAction={() => deleteComment(comment.commentId, comment.commentData.authorId)}
                            />
                        ) : null
                    }
                </span>
            </div>
            )}
        </div>
    )
}

const mapDispatchToProps = (dispatch) => {
  return {
    postComment: (comment) => dispatch(postComment(comment)),
    deleteComment: (commentToDelete) => dispatch(deleteComment(commentToDelete)) 
  }
} 

const mapStateToProps = (state) => {
    return {
        auth: state.firebase.auth,
        commentError: state.commentsReducer.commentError,
    }
} 

export default connect(mapStateToProps, mapDispatchToProps)(Comments);

这也是我尝试过的,我提到过,但并不完全有效,呵呵

    useEffect(() => {

        const listener = firestore
        .collection('posts')
        .doc(slug)
        .collection('comments')
        .onSnapshot((snapshot) => {
            let _comments = [];
            snapshot.forEach(commentSnapshot => {
            _comments.push(commentSnapshot.data());
            setComments(_comments);

            });

            _comments.map((comment) => { 
                return comment.authorRef.get().then(snapshot => {

                    const { name, profilePictureURL } = snapshot.data();
                    setAuthorInfo({ name, profilePictureURL });
                    if (snapshot.data()) {
                        console.log(authorInfo.profilePictureURL)
                    }

            }) })

        }, (error) => {
            console.log(error);
        });

        return () => listener();

    }, [firestore, slug, comments, authorInfo]);
4

3 回答 3

1

我不是 React 方面的专家,但可能DocumentReference有助于参考存储在 Firestore 中的 URL。在这里,您可以找到完成这项工作的文档。我想 URL 与用户 ID 相关联,因此您也可以使用它来获取图像 URL。

于 2020-04-03T00:51:01.343 回答
0

只需在需要呈现用户个人资料图片的任何地方使用它

<img src={auth.photo} />

并确保你在 App.js 的 App() 中有这个

useEffect(() => {
    auth.onAuthStateChanged((authUser) => {
      console.log("user is ", authUser);
      if(authUser){
        dispatch(login({
          uid: authUser.uid,
          photo: authUser.photoURL,
          email: authUser.email,
          displayName: authUser.displayName,
        }))
      }
      else{
        dispatch(logout());
      }
    })
  }, [dispatch])

于 2021-01-20T20:05:29.327 回答
0

我不确定您是否可以获得不是当前登录用户的 Firebase 用户的信息。

我的建议是将每个用户的信息存储在数据库中,然后每次用户登录时,如有必要,您可以更新数据库。然后,当显示用户的评论时,您在数据库中查找该用户的图片。

于 2020-04-03T02:02:43.857 回答