iOS16设备上Expo Go上传图片至Firebase Storage崩溃求助
Expo Go + iOS16 上传Firebase Storage崩溃问题排查与修复
问题场景
仅在iOS16设备的Expo Go应用中上传图片至Firebase Storage时崩溃,iOS15.7及安卓设备无此异常,升级iOS16后问题出现。
代码问题排查与修复方案
1. 移除无意义的await调用
你的setImageFiles函数中,对同步字符串方法substring使用await完全多余,会导致异步逻辑混乱,引发状态更新异常:
// 错误写法 const firstFilename = await postImage1.substring(postImage1.lastIndexOf('/') + 1); // 修复后 const firstFilename = postImage1.substring(postImage1.lastIndexOf('/') + 1);
同理,secondFilename行的await也需要移除。
2. 替换XHR blob生成方式为Expo官方API
iOS16的WebView环境对原生XHR的blob处理存在兼容性问题,建议使用expo-file-system生成blob,更适配Expo Go环境:
import * as FileSystem from 'expo-file-system'; const uploadImage1ToStore = async () => { setUploading(true); try { // 用expo-file-system读取文件并转为blob const base64 = await FileSystem.readAsStringAsync(postImage1, { encoding: FileSystem.EncodingType.Base64 }); const blob = new Blob( [Uint8Array.from(atob(base64), c => c.charCodeAt(0))], { type: 'image/jpeg' } // 根据实际图片类型调整 ); const ref = firebase.storage().ref().child(firstImageFile); const snapshot = await ref.put(blob); const downloadUrl = await snapshot.ref.getDownloadURL(); setPostImage1Url(downloadUrl); blob.close(); } catch (error) { Alert.alert(error.message); } finally { setUploading(false); } };
3. 升级Firebase相关SDK版本
旧版本Firebase Storage SDK未适配iOS16系统变化,检查并升级依赖到最新稳定版:
npm install firebase@latest
4. 修正useEffect的异步与清理逻辑
原代码中直接调用unsubscribe会导致网络监听失效,且未处理异步函数的依赖问题,调整如下:
useEffect(() => { const unsubscribe = NetInfo.addEventListener((state) => { setIsConnected(state.isConnected); if (!state.isConnected) { Alert.alert('Network Error!', 'You are not connected to the internet'); } }); const initImageFiles = async () => { setUploading(true); const timeStamp = new Date().toISOString(); if (postImage1) { const firstFilename = postImage1.substring(postImage1.lastIndexOf('/') + 1); setFirstImageFile(`${timeStamp}${firstFilename}`); } else if (postImage2) { // 避免双图存在时逻辑冲突 const secondFilename = postImage2.substring(postImage2.lastIndexOf('/') + 1); setSecondImageFile(`${timeStamp}${secondFilename}`); } setUploading(false); }; initImageFiles(); return () => unsubscribe(); // 用useEffect返回值做清理 }, [postImage1, postImage2]); // 添加依赖项避免stale state
5. 检查iOS16权限配置
确认app.json中已正确配置照片访问权限,iOS16对权限弹窗逻辑有调整:
{ "expo": { "ios": { "infoPlist": { "NSPhotoLibraryUsageDescription": "需要访问照片库以上传图片", "NSPhotoLibraryAddUsageDescription": "需要访问照片库以上传图片" } } } }
内容的提问来源于stack exchange,提问作者Oao
相关产品推荐
相关产品推荐

