Redux-saga+React Native中RNFS读取图片无响应且无报错求助
问题分析与解决方案
看起来你的RNFS.readFile调用卡住了,既没执行后续代码也没抛出错误,大概率是几个细节没处理对,我帮你逐个排查:
1. 模板字符串语法错误(隐藏坑)
先看你的storage ref代码:
const storageRef = firebase.storage().ref('${userId}').child("mycards/logos/");
这里你用了单引号包裹${userId},但模板字符串必须用反引号()才能解析变量!现在你的storage路径是字面量${userId}`,而不是实际的用户ID,不过这不是当前卡住的直接原因,但必须先修正:
const storageRef = firebase.storage().ref(`${userId}`).child("mycards/logos/");
2. 图片读取编码错误(核心问题)
RNFS的readFile默认编码是utf8,但图片是二进制文件,用utf8读取会导致解析异常,甚至卡住异步操作。你需要指定base64编码,这也是Firebase Storage支持的上传格式:
// 修正读取方式,添加base64编码参数 const cardLogo = yield call(RNFS.readFile, logo.uri, 'base64');
同时,Firebase上传base64字符串时,应该用putString方法而不是put,还要指定文件类型的metadata,否则Storage会把它当成纯文本处理:
// 替换原有的put调用,改用putString并指定contentType const snapshot = yield call([storageRef, storageRef.putString], cardLogo, 'base64', { contentType: 'image/png' // 根据你的图片类型调整,比如image/jpeg }); // 别忘了获取实际的下载URL(原代码里直接用put的返回值是不对的) const logoStorageUrl = yield call([snapshot.ref, snapshot.ref.getDownloadURL]);
3. 文件路径与权限问题
如果上面的修正后还是卡住,检查以下两点:
- 确认
logo.uri的格式:iOS上必须是file://开头的完整路径,Android上如果是外部存储(比如相册),需要申请对应的权限:- Android 12及以下:
READ_EXTERNAL_STORAGE - Android 13+:
READ_MEDIA_IMAGES
- Android 12及以下:
- 打印
logo.uri的具体值,手动验证路径是否存在,比如用RNFS的exists方法先检查:
const exists = yield call(RNFS.exists, logo.uri); console.log("File exists:", exists); if (!exists) throw new Error("Logo file not found");
4. 添加局部错误捕获
虽然外层saga有try/catch,但给uploadCardLogo添加自己的错误捕获可以更精准地定位问题:
function* uploadCardLogo(logo, userId) { console.log("uploading card logo"); const storageRef = firebase.storage().ref(`${userId}`).child("mycards/logos/"); console.log("storage ref fetched " + logo.uri); try { const exists = yield call(RNFS.exists, logo.uri); if (!exists) throw new Error(`File not found at ${logo.uri}`); const cardLogo = yield call(RNFS.readFile, logo.uri, 'base64'); console.log("reading file done"); const snapshot = yield call([storageRef, storageRef.putString], cardLogo, 'base64', { contentType: 'image/png' }); const logoStorageUrl = yield call([snapshot.ref, snapshot.ref.getDownloadURL]); console.log("Logo has been updated =", logoStorageUrl); return logoStorageUrl; } catch (error) { console.error("Upload logo failed:", error); throw error; // 抛给外层saga处理 } }
按这些步骤修正后,应该就能解决读取卡住的问题了。
内容的提问来源于stack exchange,提问作者Sumanth Jois
相关产品推荐
相关产品推荐

