React Native iOS端上传Base64图片到Firebase出现uri.substring错误如何解决
问题根因
你代码里的myImage本身就是纯Base64编码字符串,不是包含uri字段的对象,所以执行const {uri} = myImage时,uri拿到的就是undefined,后续调用uri.substring自然会抛出你遇到的报错。而且你渲染图片时也是直接把myImage拼到Data URI里使用,也验证了它是纯Base64字符串,不是文件路径对象。
另外Firebase Storage的putFile方法仅支持传入本地文件路径,不支持直接传入Base64字符串或者Data URI,这也是你需要调整的逻辑点。
解决方案
步骤1:移除错误的uri解构逻辑
不需要从myImage里读取不存在的uri字段,直接用拿到的Base64字符串拼接标准Data URI即可。
步骤2:将Base64转成Blob对象上传
Firebase Storage的put方法支持直接上传Blob对象,不需要依赖本地文件路径,适配Base64上传场景。
修改后的完整代码如下:
// 这里拿到的myImage是纯Base64字符串,不需要解构uri const { myImage } = props.route.params; const uploadImage = async () => { setUploading(true); setTransferred(0); try { // 拼接成标准Data URI,如果上游传递的myImage已经带了data:image/xxx;base64,前缀,可跳过这步 const dataUri = `data:image/png;base64,${myImage}`; // 自定义文件名,可根据需求调整,比如加时间戳避免重名 const filename = `upload_${Date.now()}.png`; // 将Data URI转为Blob对象 const blob = await fetch(dataUri).then(res => res.blob()); // 用put方法上传Blob,不要用putFile const task = storage() .ref(filename) .put(blob); // 原有进度监听逻辑保留即可 task.on('state_changed', snapshot => { setTransferred( Math.round(snapshot.bytesTransferred / snapshot.totalBytes) * 10000 ); }); await task; Alert.alert( '上传成功', '你的照片已经上传到Firebase云存储!' ); } catch (e) { console.error('上传失败:', e); } finally { setUploading(false); } };
额外注意事项
- 如果上传的图片格式不固定为png,需要在上游传递
myImage的时候同时传递图片格式参数,拼接Data URI时动态替换格式后缀 - 如果非要使用
putFile方法,需要先把Base64字符串写入应用本地沙盒生成临时文件,拿到本地文件路径后再调用putFile,该方案性能比直接传Blob差,非必要不推荐
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

