Я новичок в разработке React. В настоящее время я хочу добиться того, чтобы пользователи могли отправлять загруженные изображения. Эта функция аналогична загрузке картинок в мессенджере и может быть отправлена вместе с текстом. Ниже приведен мой текущий код:
import React, { useState } from 'react'
import "./ChatInput.css"
import { useStateValue } from './StateProvider';
import db from './firebase';
import firebase from 'firebase';
import { storage } from './firebase';
function ChatInput({channelName, channelId}) {
const [input, setInput] = useState("");
const [{user}] = useStateValue();
const [image, setImage] = useState(null);
const [imageUrl, setImageUrl] = useState("");
const sendMessage = (e) => {
e.preventDefault();
if (channelId){
db.collection('courses').doc(channelId).collection('messages').add({
message:input,
timestamp:firebase.firestore.FieldValue.serverTimestamp(),
user:user.displayName,
userImage: user.photoURL,
});
}
setInput("");
};
const fileSelectedHandler = e => {
if (e.target.files[0]) {
setImage(e.target.files[0]);
}
};
const fileUploadedHandler = () => {
const uploadTask = storage.ref(`images/${image.name}`).put(image);
uploadTask.on(
"state_changed",
snapshot => {},
error => {
console.info(error);
},
() => {
storage
.ref("images")
.child(image.name)
.getDownloadURL()
.then(url => {
setImageUrl(url)
});
}
);
}
return (
<div className = "chatInput">
<form>
<input
value = {input}
onChange = {(e)=>setInput(e.target.value)}
placeholder = {`Message #${channelName?.toLowerCase()}`} />
<button type = "submit" onClick = {sendMessage}>SEND</button>
</form>
<input type = "file" onChange = {fileSelectedHandler}/>
<button type = "submit" onClick = {fileUploadedHandler}>UPLOAD</button>
<br />
<img src = {imageUrl} alt = "" />
</div>
);
}
export default ChatInput;
Потому что картинка хранится в firebase-storage, а сообщение, отправленное пользователем, хранится в firestore. Я не знаю, как соединить их двоих. Я надеюсь, что кто-то может дать ответы и предложения по коду будет лучше.
🤔 А знаете ли вы, что...
С React можно легко интегрировать с другими библиотеками и фреймворками.
Обычно вы сохраняете путь к файлу в хранилище или URL-адрес загрузки (или и то, и другое) в качестве полей в соответствующем документе. Обычно это предполагает, что вы сначала загружаете в хранилище, а затем пишете документ. Но вы всегда можете обновить документ после завершения загрузки.
Некоторые люди также используют тот же случайно сгенерированный идентификатор документа, что и имя файла в хранилище, поэтому вы всегда знаете, как перейти от одного к другому.
const [messages, setMessages] = useState([]);
useEffect(()=>{
db
.collection('courses')
.doc(channelId)
.collection('messages')
.orderBy("timestamp","desc")
.onSnapshot((snapshot)=>
setMessages(
snapshot.docs.map((doc)=>({
id: doc.id,
data: doc.data()
}))
)
)
},[]);
return(
{
messages.map(({id,data:{content,user,timestamp,userImage}})=>(
<Message
message = {content}
user = {user}
id = {id}
key = {id}
createdAt = {timestamp}
senderImgSrc = {userImage}
/>
))
}
)
Поскольку вы храните imageUrl
в firestore, вам больше не нужно искать свое хранилище, поскольку URL-адрес останется прежним. Вот почему я использую URL-адрес, который хранится в хранилище огня.
Вы можете создать свой собственный компонент сообщения.