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

Firebase存储与Firestore音频上传遇Range Error及网络请求错误求助

问题诊断与修复方案

核心问题分析

你遇到的Range Error、网络请求错误以及音频仅上传少量字节的问题,大概率是DocumentPicker获取的音频文件URI无法被fetch完整读取导致的:

  • 当copyToCacheDirectory: false时,直接通过原URI fetch可能因系统权限限制,只能读取文件的部分内容,生成不完整的Blob。
  • 音频文件体积通常远大于图片,这种不完整Blob会触发Firebase上传的Range Error,同时导致上传内容缺失。

修复步骤

1. 修改DocumentPicker配置,启用缓存目录复制

将copyToCacheDirectory设为true,确保获取到的是可完整读取的本地缓存文件URI:

async function pickAudio() {
  try {
    const result = await DocumentPicker.getDocumentAsync({
      type: "audio/*",
      copyToCacheDirectory: true, // 改为true,确保文件可完整读取
    });

    if (!result.canceled) {                                                                                             
      setAudioFile(result.assets[0].uri);
      setAudioFilename(result.assets[0].name);
      const response = await fetch(result.assets[0].uri);
      const blob = await response.blob();
      // 新增:验证Blob大小,确认文件完整
      console.log("音频Blob大小:", blob.size);
      setAudioBlob(blob);
    }
  } catch (error) {
    console.error("选择音频出错:", error);
  }
}

2. 优化音频Blob的生成方式(备选方案)

如果启用缓存后仍有问题,可通过react-native-fs直接读取文件内容生成Blob,避免fetch的权限问题:

// 先安装依赖:npm install react-native-fs
import RNFS from 'react-native-fs';

async function pickAudio() {
  try {
    const result = await DocumentPicker.getDocumentAsync({
      type: "audio/*",
      copyToCacheDirectory: true,
    });

    if (!result.canceled) {                                                                                             
      setAudioFile(result.assets[0].uri);
      setAudioFilename(result.assets[0].name);
      // 用RNFS读取文件内容,再转为Blob
      const fileContent = await RNFS.readFile(result.assets[0].uri, 'base64');
      const blob = await fetch(`data:audio/${result.assets[0].type};base64,${fileContent}`).then(res => res.blob());
      console.log("音频Blob大小:", blob.size);
      setAudioBlob(blob);
    }
  } catch (error) {
    console.error("选择音频出错:", error);
  }
}

3. 上传时添加错误处理与进度监控

在upload函数中添加上传进度监听,便于排查网络请求错误:

async function upload(audioBlob, imageBlob) {
  const audioStorageRef = ref(storage, "audioSermon/" + new Date().getTime());
  const audioUploadTask = uploadBytesResumable(audioStorageRef, audioBlob);

  // 监听音频上传进度与错误
  audioUploadTask.on('state_changed', 
    (snapshot) => {
      const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
      console.log(`音频上传进度:${progress}%`);
    },
    (error) => {
      console.error("音频上传错误:", error);
      // 根据错误类型处理:比如重新上传、提示用户
    }
  );

  const imageStorageRef = ref(storage, "albumArt/" + new Date().getTime());
  const imageUploadTask = uploadBytesResumable(imageStorageRef, imageBlob);

  try {
    const [audioSnapshot, imageSnapshot] = await Promise.all([
      audioUploadTask,
      imageUploadTask,
    ]);

    const audioDownloadUrl = await getDownloadURL(audioSnapshot.ref);
    const imageDownloadUrl = await getDownloadURL(imageSnapshot.ref);

    await saveRecord(
      audioDownloadUrl,
      imageDownloadUrl,
      title,
      preacher,
      series,
      new Date().getTime()
    );

    setAudioFile("");
    setImageFile("");
    console.log("上传完成");
    navigation.navigate("admin/adManage/audioSermon");
  } catch (error) {
    console.error("获取下载链接或保存记录出错:", error);
  }
}

验证要点

  • 选择音频后,查看控制台打印的Blob大小,确认与原文件大小一致。
  • 上传时监控进度,确保进度能达到100%,没有中途中断。

内容的提问来源于stack exchange,提问作者lyon98.dbios

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:35:33