Поэтому, когда я отправляю комментарий пользователю, я думал о том, чтобы сохранить URL-адрес его изображения профиля на объекте комментария, чтобы я мог легко получить к нему доступ, но я подумал, что это не сработает, потому что, если они меняют изображение своего профиля или удаляют его комментарий все равно будет содержать их старый URL, я также пытался сохранить ссылку на пользователя в Firestore, но я не уверен, что сделал это неправильно или что-то еще, потому что у меня постоянно возникали ошибки.
TLDR - я спрашиваю, знает ли кто-нибудь способ хранения и доступа к URL (который может измениться в будущем) для конкретного c комментария.
Извините, если я не уточнил или не объяснил ну, я довольно новичок в 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]);