在我的 React 应用程序中,我主要有三个连接到 firebase 的功能。 firebase 身份验证、实时聊天,而这第三个需要 firebase 存储。我想上传带有聊天消息的图像。
当我尝试上传图像时,当我尝试 console.log(url)
时,控制台会给出此错误
我想获取下载的图像 url 并将其存储在我的 firestore 数据库中,然后在我的 Message.js
组件中使用该 url。
我的 Chat.js 组件
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>
);
消息组件
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 安全性规则
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;
}
}
}
最佳答案
转到 Firebase 控制台,然后选择您正在处理的项目,然后转到存储,然后选择规则。
如果您使用 Firestore 或数据库,请检查规则。另一个问题可能是您尚未添加项目的 SHA。我们允许每个人更改存储方式的公共(public)访问。
就您的情况而言,正如您所评论的,问题可能是安全访问。 Here is a link to google documenations
我建议您在使用 Amazon AWS、Firebase 或任何类型的 API 等任何平台之前阅读文档。
再次检查 - 检查文件的地址,我重新检查了错误。您的安全规则是正确的,我认为您应该使用文档中的一些示例。
关于reactjs - 为什么我在 React 应用程序中没有获取 Firebase 存储文件 url?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67537825/