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

Hermes引擎下Uint16Array异常致Firebase二进制上传失败

解决Hermes引擎下Firebase上传二进制数据异常问题

问题概述

在iOS React Native应用(基于Hermes引擎)中,处理ESP32传输的字节数组并上传至Firebase时,移动端生成的文件为字符形式(如69,120,67,90),而非预期的原始二进制数据;但相同代码在Node环境下运行正常。核心原因是Hermes对TypedArray的处理存在差异,将其识别为字典对象(打印结果为{ '0': 30789, '1': 23107 }),导致Firebase无法正确解析二进制格式。

解决方案

方案1:将TypedArray转为普通数组后重构

通过Array.from()将TypedArray转为原生数组,再重新构建Uint8Array,确保Firebase能识别为二进制数据:

async function uploadBlob(bytes){
  const newByteRef = doc(collection(db, "PPG"));
  const url = 'PPG/'+newByteRef.id;
  const storageRef = ref(storage, url);
  
  // 先转普通数组,再重构Uint8Array
  const rawArray = Array.from(bytes);
  const U8bytes = new Uint8Array(rawArray);

  try{
    await uploadBytes(storageRef, U8bytes);
    const downloadUrl = await getDownloadURL(storageRef);
    
    const data = {
      date: Date.now(),
      url: downloadUrl.split("/").slice(-1)[0]
    };
    await setDoc(newByteRef, data);
  } catch (error){
    console.log(error);
  }
}

方案2:使用Blob包装二进制数据

Hermes对Blob的支持更稳定,直接用Blob包装TypedArray后上传:

async function uploadBlob(bytes){
  const newByteRef = doc(collection(db, "PPG"));
  const url = 'PPG/'+newByteRef.id;
  const storageRef = ref(storage, url);
  
  // 用Blob包装二进制数据,指定MIME类型为二进制流
  const blob = new Blob([bytes], { type: 'application/octet-stream' });

  try{
    await uploadBytes(storageRef, blob);
    const downloadUrl = await getDownloadURL(storageRef);
    
    const data = {
      date: Date.now(),
      url: downloadUrl.split("/").slice(-1)[0]
    };
    await setDoc(newByteRef, data);
  } catch (error){
    console.log(error);
  }
}

方案3:修复Base64上传异常(针对复现案例)

绕开Hermes对uploadString的Base64解析问题,手动解码Base64为Uint8Array后上传:

const base64String = "eEU=";
const storageRef = ref(storage, url);

// 手动解码Base64为Uint8Array
const decodeBase64 = (base64) => {
  const binaryString = atob(base64);
  const bytes = new Uint8Array(binaryString.length);
  for (let i = 0; i < binaryString.length; i++) {
    bytes[i] = binaryString.charCodeAt(i);
  }
  return bytes;
};

const binaryData = decodeBase64(base64String);
await uploadBytes(storageRef, binaryData);

辅助优化:拼接TypedArray时转普通数组处理

针对concatTypedArrays函数,转普通数组拼接可避免Hermes的TypedArray异常:

concatTypedArrays(base64String) {
    const byteArr = new Uint16Array(base64String.length/2);
    for (let i = 0; i < base64String.length; i+=2) {
      const highByte = base64String.charCodeAt(i) << 8;
      const lowByte = base64String.charCodeAt(i + 1);
      byteArr[i / 2] = highByte | lowByte;
    }

    // 转普通数组拼接后再转回Uint16Array
    const combinedArray = [...Array.from(this.arr), ...Array.from(byteArr)];
    this.arr = new Uint16Array(combinedArray);

    console.log(this.arr);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:53:12