为啥我没有在我的 react 应用程序中获取 firebase 存储文件 url?
Posted
技术标签:
【中文标题】为啥我没有在我的 react 应用程序中获取 firebase 存储文件 url?【英文标题】:Why am I not getting firebase storage files url in my react app?为什么我没有在我的 react 应用程序中获取 firebase 存储文件 url? 【发布时间】:2021-08-04 20:01:55 【问题描述】:在我的 React 应用程序中,我主要拥有三个连接到 firebase 的功能。 firebase auth,实时聊天,这第三个需要 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 />
</div>
</div>
);
;
firebase sequrity 规则
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;
Link to live website
【问题讨论】:
检查文件地址是否有误。确定该文件不存在,请检查您从 api 获取的 url。 是的,当我单击 firebase api URL 时,它表示文件不存在,我正在获取 api 的 url 也托管在 firebase 上,但我正在使用 netlify 链接进行生产。你是说我应该检查我的 Firebase 网址? 是的,检查您获取的网址并手动下载文件。至少您可以知道问题出在哪里,在 Firebase 规则中或在您的代码中。 我访问了控制台错误 url 但它显示我对象这个对象:“错误”:“代码”:403,“消息”:“权限被拒绝。无法执行此操作”我不明白怎么了? 我们明白了,问题出在 Firebase 规则中。 Google 提供了安全规则,我们可以通过这些规则控制人们访问我们的 Firebase 存储。我正在发布一个答案,请检查它。 【参考方案1】:转到 firebase 控制台,然后选择您正在处理的项目,然后转到存储,然后转到规则。
如果您使用的是 Firestore 或数据库,请检查规则。另一个问题可能是您没有添加项目的 SHA。我们允许每个人更改存储方式的公共访问权限。
在您的情况下,正如您所评论的,问题可能是安全访问。 Here is a link to google documenations
我建议您在使用任何平台(如 Amazon AWS、firebase 或任何类型的 API)之前阅读文档。
另一个检查 - 检查文件的地址,我重新检查了错误。您的安全规则是正确的,我认为您应该使用文档中的一些示例。
【讨论】:
感谢 Vijay 的回答,我更改了存储规则,但现在我上传了显示错误代码 404 而不是 403 的图像。未捕获(承诺)FirebaseError: Firebase Storage: Object 'assetsdiscord/Screenshot ( 226).png' 不存在。 (storage/object-not-found) "error": "code": 404, "message": "Not Found. could not get object", "status": "GET_OBJECT" 我查看了图片的api链接,如下:firebasestorage.googleapis.com/v0/b/… 也许我的 react 应用有问题? 你的应用和firebase服务器没有问题,你应该冷静和耐心。看到它说找不到对象(我不知道 javascript,因为我是一名 android 开发人员),但在 java 中这意味着 StorageReferece 未初始化。根据错误可能有两个错误,一个是对象有问题,第二个是文件的位置(您要上传的文件或您要上传的位置)不正确。耐心一点,一步一步看,错在哪里。 感谢 Vijay 的所有帮助,我会看一看。【参考方案2】:当您提到上传时,您使用的是“assets_discord”,但是当您想要获取 URL 时,您指的是“assetsdiscord”
【讨论】:
以上是关于为啥我没有在我的 react 应用程序中获取 firebase 存储文件 url?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Postman 在我的 React 应用程序中接收到 express 会话 cookie 而不是我的 post 请求
React Native 已经有了异步存储。为啥我应该在我的 react native 应用中使用 Redux 和 Redux Thunk?
为啥 CORS 不能在我的 express/react 应用程序上运行?