You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS上传文件到Firebase Storage首次点击报对象不存在错误

问题根本原因

你代码中的put()是异步IO操作,没有等待它执行完成就直接调用getDownloadURL(),首次执行时文件还没上传到Firebase Storage,所以会报对象不存在的错误。第二次点击时第一次触发的上传操作已经完成,对应路径的文件已经存在,所以可以正常获取下载地址。路径中的/转义为%2F是HTTP协议标准的URL编码行为,不是报错的原因。


错误点明细

  • firebase.storage().ref(path).put(blob)执行后不会阻塞后续代码运行,触发上传后立刻调用getDownloadURL()时文件还未写入Storage,直接触发404
  • 第二次点击时第一次上传流程已经执行完成,所以可以正常返回地址
  • URL编码为%2F是Firebase Storage的正常行为,无需修改

修复方案

方案1:使用async/await统一异步逻辑(推荐)

按顺序等待异步操作执行完成后再走后续流程:

async function uploadFile() {
    console.log('starting UPLOAD ========');
    const blob = await fetch(mediaBlobUrl).then((r) => r.blob());
    const path = '/recordings/one';
    const storageRef = firebase.storage().ref(path);
    // 等待上传完成
    await storageRef.put(blob);
    console.log('Uploaded complete');
    // 上传完成后再获取下载地址
    const downloadUrl = await storageRef.getDownloadURL();
    setURL(downloadUrl);
    console.log(`====> setURL is ${downloadUrl} <=======`);
}

方案2:在put的成功回调中获取下载地址

如果保留原有Promise链式写法,把获取地址的逻辑移入上传成功回调即可:

async function uploadFile() {
    console.log('starting UPLOAD ========');
    const blob = await fetch(mediaBlobUrl).then((r) => r.blob());
    const path = '/recordings/one';
    const storageRef = firebase.storage().ref(path);
    storageRef
      .put(blob)
      .then(function (snapshot) {
        console.log('Uploaded complete');
        // 上传完成后再获取下载地址
        return storageRef.getDownloadURL();
      })
      .then(downloadUrl => {
        setURL(downloadUrl);
        console.log(`====> setURL is ${downloadUrl} <=======`);
      });
}

内容的提问来源于stack exchange,提问作者jdog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 14:30:01