问题描述
我有一个带有 Firebase 后端的 React 应用。我在数据库中有一个用户集合,用于存储用户的 photoURL。
当用户对帖子发表评论时,不是每次都将该 photoURL 保存到评论集合中,我只想呈现用户集合中的 photoURL。
这样,如果用户更新他们的 photoURL,它会更新所有评论,而且不会有重复的数据。
对于每条评论,我都将 uid 保存在评论集合中。我只是无法弄清楚如何映射所有评论并获取 uid 并使用它从用户集合中获取 photoURL。以下是我目前所拥有的。
我是 React 的新手,如果这是一个简单的修复,我深表歉意。
const [comments,setComments] = useState([])
// This is used to get all the comments
useEffect(() => {
let unsubscribe
if (postId) {
unsubscribe = db.collection('posts').doc(postId).collection('comments').orderBy('timestamp','desc').onSnapshot((snapshot) => {
setComments(snapshot.docs.map((doc) => doc.data()))
})
}
return () => {
unsubscribe()
}
},[postId])
// This is for adding the comment to the comments collection
const postComment = (event) => {
event.preventDefault()
db.collection('posts').doc(postId).collection('comments').add({
text: comment,username: user.displayName,timestamp: firebase.firestore.FieldValue.serverTimestamp(),photoURL: user?.photoURL,// This does not save anything because it's taking form auth user and not user collection
uid: user?.uid
})
setComment('')
setCommentActive(true)
setCommentsArrow(!commentsArrow)
}
// This is a function to get the photoURL of any user based on the uid
async function getimageURL(uid) {
return (await db.collection("users").doc(uid).get()).data().photoURL
}
// Rendering the comments
return (
<div style={{ transition: "height 0.3s linear" }} className={commentActive ? null : "hidden"}>
<div className="post__comments">
{comments.map((comment) => (
<div className="post__comment">
<Avatar
className="post__avatar"
alt=""
src={getimageURL(comment.uid)} // Calls the getimageURL function and passes in the uid from the comment
/>
<p><strong>{comment.username}</strong> {comment.text}</p>
</div>
))}
</div>
</div>
)
解决方法
以下是我认为可行的 2 个选项:
- 我看到您将用户的 UID 存储在评论文档中,然后向 Firestore(用户集合)发出单独的请求,然后从该文档中获取他们的 photoURL。
- 这是我更喜欢的方式,而且似乎是最可行的方式,但要这样做,您必须将用户图像存储在 Firebase Storage 或任何存储服务中。在那里您可以像
/images/<user_uid>
一样构建您的目录。因此,如果我在评论中的 UID 是“uid123”,那么您将在 Firebase Storage 中查找该图像。
来自 Firebase 存储的下载 URL 如下所示:
https://firebasestorage.googleapis.com/v0/b/<project_id>.appspot.com/o/users%2F<userId>.png?alt=media&token=token
现在它的末尾确实有该令牌,因此您可能必须使用 getDownloadURL 方法或从 Google Cloud Console 公开您的存储桶。但 URL 的格式将保持一致,即 https://domain.tld/path/image.png
这意味着用户不能只是简单地粘贴图片 URL 来更新他们的照片,而是他们必须上传图片并且您必须将其存储在某个地方。
如果您不想使用存储或上述第二种方法,那么您必须额外调用数据库以获取用户的个人资料图片。
编辑: 从 UID 获取用户图片 URL 的函数:
async function getImageURL(uid) {
return (await db.collection("users").doc(uid).get()).data().photoURL
}
然后在下面的组件中:
{comments.map((comment) => (
<div className="post__comment">
<Avatar
className="post__avatar"
alt=""
src={getImageURL(comment.uid)}
/>
<p><strong>{comment.username}</strong> {comment.text}</p>
</div>
))}