Donc, lorsque j'utilise un commentaire, je pensais stocker l'URL de leur photo de profil sur l'objet de commentaire afin que je puisse y accéder facilement, mais j'ai pensé que cela ne fonctionnerait pas car s'ils modifient leur photo de profil ou s'ils la suppriment , le commentaire contiendra toujours leur ancienne URL, j'ai également essayé de stocker la référence à l'utilisateur dans Firestore, mais je ne sais pas si je l'ai mal fait ou quoi parce que j'ai continué à rencontrer des erreurs.
TLDR - I je demande si quelqu'un connaît un moyen de stocker et d'accéder à une URL (qui pourrait changer à l'avenir) pour un commentaire spécifique.
Désolé si je n'ai pas clarifié ou expliqué les choses également, je suis assez nouveau pour React comme vous pouvez probablement déjà le dire. Et je peux essayer d'expliquer les choses mieux si quelqu'un a des questions, alors oui merci d'avoir lu ceci et merci d'avance.
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]);
C'est aussi quelque chose que j'ai essayé et que j'ai mentionné, mais n'a pas vraiment fonctionné, hein
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);
3 Réponses :
Je ne suis pas un expert de React, mais j'utilise peut-être DocumentReference
peut être utile pour faire référence à l'URL stockée dans Firestore. Ici vous pouvez trouver la documentation pour faire ce travail. J'imagine que l'URL est liée à l'ID utilisateur, vous pouvez donc également l'utiliser pour obtenir l'URL de l'image.
Merci d'avoir laissé un commentaire, et oui, j'ai stocké une référence de document, mais je n'ai pas implémenté les choses correctement, je ne sais pas comment je mettrais la référence dans le même objet avec les données de commentaire. Voici le code où j'ai essayé de faire cela: pastebin.com/bmdVqRdb
Je ne suis pas familiarisé avec React mais peut-être ceci peut vous aider.
Oui, merci Fernando c'est ce dont je parlais, je vais le lire
Je ne sais pas si vous pouvez obtenir des informations sur un utilisateur Firebase qui n'est pas l'utilisateur actuellement connecté.
Ce que je suggère, c'est de stocker des informations pour chacun de vos utilisateurs dans votre base de données, puis chaque fois qu'un utilisateur est connecté, vous pouvez mettre à jour votre base de données si nécessaire. Ensuite, lorsque vous affichez le commentaire d'un utilisateur, vous recherchez l'image dans votre base de données pour cet utilisateur.
Les commentaires sont uniquement destinés aux utilisateurs authentifiés, mais pourriez-vous me montrer votre idée dans le code si cela ne vous dérange pas? et j'apprécie que vous essayiez de m'aider
Il n'y a pas grand chose à montrer dans le code, c'est surtout la façon dont vous structurez vos données. Ce que je dis, c'est que, lorsque vous recevez vos commentaires de Firestore, une propriété de ces données de commentaire devrait être l'uid de l'utilisateur qui a fait le commentaire, au lieu de la photo de profil. Une fois que vous avez cet uid, vous pouvez rechercher l'image de Firestore, où vous auriez une collection users
pour stocker les données utilisateur. Et pour vous assurer que l'image est à jour, chaque fois qu'un utilisateur se connecte, vous pouvez mettre à jour sa photo de profil dans Firestore si elle a changé.
Utilisez simplement ceci partout où vous avez besoin de rendre la photo de profil de l'utilisateur
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])
et assurez-vous que vous l'avez dans votre App () dans App.js
<img src={auth.photo} />