React Native项目iOS端上传图片至Firebase Storage时崩溃
iOS端Expo ImagePicker选图后上传Firebase Storage崩溃解决
问题概述
使用Expo ImagePicker成功选择图片并更新状态,但仅iOS端调用Firebase Storage上传函数时应用崩溃,安卓端可正常工作。
核心原因
iOS上Expo ImagePicker返回的图片URI为file://开头的本地路径,直接用fetch()读取会触发底层权限或跨域错误,导致应用崩溃。
解决方案
方案1:使用expo-file-system读取文件(推荐)
- 安装依赖
npx expo install expo-file-system
- 修改上传函数,通过FileSystem读取文件内容并转为Blob
import * as FileSystem from 'expo-file-system'; import { getStorage, ref, uploadBytes } from 'firebase/storage'; export const uploadImage = async (url: string, clubName: string) => { const storage = getStorage(); const reference = ref(storage, `home_image/${clubName}_main.png`); // 读取本地文件为base64格式 const base64Content = await FileSystem.readAsStringAsync(url, { encoding: FileSystem.EncodingType.Base64 }); // 将base64转换为Blob const blob = new Blob( [Uint8Array.from(atob(base64Content), char => char.charCodeAt(0))], { type: 'image/png' } ); await uploadBytes(reference, blob); }
方案2:修复iOS URI的fetch兼容性
针对iOS平台转换URI格式,避免直接fetch本地file路径:
import { Platform } from 'react-native'; import * as FileSystem from 'expo-file-system'; import { getStorage, ref, uploadBytes } from 'firebase/storage'; export const uploadImage = async (url: string, clubName: string) => { const storage = getStorage(); const reference = ref(storage, `home_image/${clubName}_main.png`); // iOS平台转换为系统可识别的内容URI const safeUri = Platform.OS === 'ios' ? await FileSystem.getContentUriAsync(url) : url; const imageResponse = await fetch(safeUri); const imageBlob = await imageResponse.blob(); await uploadBytes(reference, imageBlob); }
额外检查项
- 确认iOS权限配置
在app.json的ios.infoPlist中添加相册权限描述:
{ "expo": { "ios": { "infoPlist": { "NSPhotoLibraryUsageDescription": "需要访问相册以选择并上传图片" } } } }
- 验证Firebase初始化
确保iOS端已正确配置GoogleService-Info.plist,Firebase初始化代码在App启动时正常执行。
内容的提问来源于stack exchange,提问作者Daniel Sem
相关产品推荐
相关产品推荐

