React Native集成Firebase v9上传图片至Storage仅显示9字节无法正常打开问题求助
解决React Native + Firebase v9上传图片仅9字节的问题
你遇到的问题其实很典型——你上传的不是实际的图片二进制数据,而是图片的路径字符串,这就是为什么文件大小只有9字节(刚好是你路径字符串的长度)。Firebase Storage的uploadBytesResumable方法需要接收Blob、File或者Uint8Array类型的二进制数据,而不是字符串路径。
问题出在哪?
看你的代码里这一行:
const uploadTask = uploadBytesResumable(storageRef, file);
这里的file参数是你通过file.substring(...)处理后的路径字符串,不是实际的文件内容,所以Firebase直接把这个字符串当成了文件内容上传,自然只有几个字节大小,根本不是图片文件。
怎么解决?
在React Native中,你需要先把图片路径对应的文件转换成二进制数据,再传给Firebase。这里分两种常见场景给出具体方案:
场景1:使用Expo的ImagePicker获取图片
如果你用的是Expo的ImagePicker,返回的uri可以通过expo-file-system读取成二进制数据:
import * as FileSystem from 'expo-file-system'; const uploadFiles = async (fileUri, name, storeKey) => { if(!fileUri){ console.log('no file exists') return; } // 从uri提取文件扩展名 const exe = fileUri.split('.').pop(); const fileName = `${name}.${exe}`; const storageRef = ref(storage, `/files/${fileName}`); // 读取文件为base64格式,再转成Uint8Array const base64Content = await FileSystem.readAsStringAsync(fileUri, { encoding: FileSystem.EncodingType.Base64, }); const fileData = Uint8Array.from(atob(base64Content), c => c.charCodeAt(0)); // 上传二进制数据 const uploadTask = uploadBytesResumable(storageRef, fileData); uploadTask.on('state_changed', null, (error) => { alert(error); }, () => { getDownloadURL(uploadTask.snapshot.ref) .then((URL) => { setDoc(doc(db, 'Store', storeKey, 'coffeeDB', name), {postImage: URL}, {merge: true}); console.log('url registered') }); } ) }
场景2:纯React Native项目(使用react-native-fs)
如果是非Expo的React Native项目,可以用react-native-fs读取文件:
import RNFS from 'react-native-fs'; const uploadFiles = async (fileUri, name, storeKey) => { if(!fileUri){ console.log('no file exists') return; } const exe = fileUri.split('.').pop(); const fileName = `${name}.${exe}`; const storageRef = ref(storage, `/files/${fileName}`); // 读取文件为base64,再转换为Uint8Array const base64Content = await RNFS.readFile(fileUri, 'base64'); const fileData = Uint8Array.from(atob(base64Content), c => c.charCodeAt(0)); const uploadTask = uploadBytesResumable(storageRef, fileData); // 后续的状态监听和下载URL逻辑和之前一致... }
额外小技巧
你也可以直接用Firebase的uploadString方法上传base64格式的内容,代码会更简洁:
// 读取到base64Content后直接上传 uploadString(storageRef, base64Content, 'base64').then(() => { getDownloadURL(storageRef) .then((URL) => { // 写入数据库的逻辑 }); });
内容的提问来源于stack exchange,提问作者maz32
相关产品推荐
相关产品推荐

