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

React Native应用上传图片到Firebase后Google Vision API失效求解

解决方案

问题定位

你的问题核心是imageUploadToFirebase函数中重写了**全局window.fetch**方法:

  • RNFetchBlob的自定义Fetch polyfill默认仅对配置的binaryContentTypes(图片/视频/音频等)做特殊处理,Google Vision API的JSON请求不属于该列表,会被错误序列化导致请求失效
  • 该全局替换是持久化的,只要执行过一次上传函数,后续所有网络请求都会使用被修改的fetch,这也能解释你补充的「先调用Vision再上传,第二次调用Vision就失效」的现象

修复方案

方案1:删除全局polyfill替换逻辑,局部使用RNFetchBlob能力(最推荐)

不要修改全局的Blob、XMLHttpRequest、fetch,直接用RNFetchBlob的自带方法上传文件,避免污染全局环境。修改后的imageUploadToFirebase代码如下:

const imageUploadToFirebase = async (imageData) => {
  let newItemKey = Firebase.database().ref().child('usersummary').push().key;
  let _name = newItemKey + 'img.jpg';
  setIsLoading(true);
  const path = Platform.OS === "ios" ? imageData.uri.replace("file://", "") : imageData.uri;
  
  try {
    // 直接用RNFetchBlob上传,不需要替换全局API
    const res = await RNFetchBlob.fs.readFile(path, 'base64');
    const blob = await RNFetchBlob.polyfill.Blob.build(res, { type: 'image/jpg;BASE64' });
    
    await Firebase.storage()
      .ref("scannedItems/" + _name)
      .put(blob);
    
    blob.close();
    const uploadedFile = await Firebase.storage()
      .ref("scannedItems/" + _name)
      .getDownloadURL();
    
    setFirebaseImageURL(uploadedFile);
    // 此处调用Vision API即可正常运行
    callGoogleVisionApi(imageData.base64);
  } catch (error) {
    console.log('上传错误:', error);
  }
}

方案2:上传完成后还原全局fetch(临时兼容方案)

如果暂时不想改上传逻辑,可以在替换全局fetch前先保存原始的fetch实例,上传完成后还原:

const imageUploadToFirebase = (imageData) => {
  // 先保存原始的全局fetch
  const originalFetch = window.fetch;
  const Blob = RNFetchBlob.polyfill.Blob;
  const fs = RNFetchBlob.fs;
  window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest;
  window.Blob = Blob;
  const Fetch = RNFetchBlob.polyfill.Fetch
  window.fetch = new Fetch({
    auto: true,
    binaryContentTypes: [
      'image/',
      'video/',
      'audio/',
      'foo/',
    ]
  }).build()
  let uploadBlob = null;
  var path = Platform.OS === "ios" ? imageData.uri.replace("file://", "") : imageData.uri
  var newItemKey = Firebase.database().ref().child('usersummary').push().key;
  var _name = newItemKey + 'img.jpg';
  setIsLoading(true)
  fs.readFile(path, "base64")
    .then(data => {
      let mime = "image/jpg";
      return Blob.build(data, { type: `${mime};BASE64` });
    })
    .then(blob => {
      uploadBlob = blob;
      return Firebase.storage()
        .ref("scannedItems/" + _name)
        .put(blob)
    })
    .then(() => {
      uploadBlob.close();
      return Firebase.storage()
        .ref("scannedItems/" + _name)
        .getDownloadURL();
    })
    .then(async uploadedFile => {
      setFirebaseImageURL(uploadedFile)
      // 还原全局fetch后再调用Vision API
      window.fetch = originalFetch;
      callGoogleVisionApi(imageData.base64)
    })
    .catch(error => {
      // 出错也要还原fetch,避免后续请求异常
      window.fetch = originalFetch;
      console.log({ error });
    });
}

额外注意点

  • 检查callGoogleVisionApi的拼写一致性,你的函数定义里误写为callGoogleVIsionApi(第二个i大写),避免调用时报错
  • 不要在callGoogleVisionApi里直接修改全局的newArr变量,建议通过返回值把结果传递出去,避免副作用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 23:21:03