In my React app, I've main three functionality which is connected to firebase. firebase auth, real-time chat, and this third one require firebase storage. I want to upload images with chat messages.
when I try to upload images, the console gives me this error when I try to console.log(url)
I want to get that downloaded image url and store it in my firestore database and then use that url inside my Message.js
component.
My Chat.js component
const [messages, setMessages] = useState([]);
const [assets, setAssets] = useState(null);
useEffect(() => {
if (channelId) {
db.collection("channels")
.doc(channelId)
.collection("messages")
.orderBy("timestamp", "desc")
.onSnapshot((snapshot) => {
setMessages(snapshot.docs.map((doc) => doc.data()));
});
}
}, [channelId]);
const sendMessage = (e) => {
e.preventDefault();
const uploadTask = storage.ref(`assets_discord/${assets.name}`).put(assets);
uploadTask.on("state_changed", () => {
storage
.ref("assetsdiscord")
.child(assets.name)
.getDownloadURL()
.then((url) => {
db.collection("assetUrl").add({
imgUrl: url,
});
console.log(url);
setAssets(null);
});
});
db.collection("channels").doc(channelId).collection("messages").add({
user: user,
message: input,
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
});
setInput("");
};
const hideInput = (e) => {
e.preventDefault();
setShowInput(!showInput);
};
return (
<div className="chat">
{channelId ? (
<>
<ChatHeader channelName={channelName} />
<div className="chat__messages">
{messages.map((message) => (
<Message
user={message.user}
message={message.message}
timestamp={message.timestamp}
assetUrl={message.imgUrl}
/>
))}
</div>
<div className="chat__input">
{showInput ? (
<>
<form action="#">
<label htmlFor="imgFiles" className="upload__img">
<AddCircle fontSize="large" />
</label>
<input
type="file"
id="imgFiles"
className="hidden"
accept="image/*"
onChange={(e) => {
if (e.target.files[0]) {
setAssets(e.target.files[0]);
}
}}
/>
<input
disabled={!channelId}
value={input}
onChange={(e) => setInput(e.target.value)}
type="text"
placeholder={`Send Message to #${channelName}`}
/>
<button
onClick={sendMessage}
className="chat__inputButton"
type="Submit"
>
Send Message
</button>
<button onClick={hideInput}>Hide</button>
</form>
</>
) : (
<p
onClick={() => setShowInput(!showInput)}
className="show__input"
>
Show
</p>
)}
</div>
</>
) : (
<>
<div className="chat__selectRoom">
<ArrowLeftIcon
style={{ fontSize: "30px" }}
className="arrow__left"
/>
<h3>Select Any Room to get Started</h3>
</div>
</>
)}
</div>
);
Message Component
const Message = ({ user, timestamp, message, assetUrl }) => {
// console.log(assetUrl);
return (
<div className="message">
<Avatar src={user.photo} />
<div className="message__info">
<h4>
{user.displayName}
<span className="message__timestamp">
{new Date(timestamp?.toDate()).toUTCString()}
</span>
</h4>
<p>{message}</p>
{/*
<ImageUpload assetUrl={assetUrl} />
*/}
<img src={assetUrl} alt="dummy" />
</div>
</div>
);
};
firebase sequrity rules
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write;
}
}
}
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if true;
}
}
}