React and Firestore - проблема с получением URL-адреса изображения профиля пользователя - PullRequest
0 голосов
/ 03 апреля 2020

Поэтому, когда я отправляю комментарий пользователю, я думал о том, чтобы сохранить 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]);

Ответы [ 2 ]

1 голос
/ 03 апреля 2020

Я не специалист по React, но, возможно, использование DocumentReference может быть полезно для ссылки на URL, хранящийся в Firestore. Здесь вы можете найти документы для этой работы. Я предполагаю, что URL-адрес связан с идентификатором пользователя, поэтому вы также можете использовать его для получения URL-адреса изображения.

0 голосов
/ 03 апреля 2020

Я не уверен, что вы можете получить информацию для пользователя Firebase, который не является текущим вошедшим в систему пользователем.

Я предлагаю хранить информацию о каждом из ваших пользователей в вашей базе данных, а затем каждый Когда пользователь вошел в систему, вы можете обновить базу данных, если это необходимо. Затем, показывая комментарий пользователя, вы ищите картинку в своей базе данных для этого пользователя.

...