React Native中无法向Supabase上传多数视频文件的求助
解决React Native中Supabase视频上传(Network request failed)的问题
核心原因
多数视频上传失败的关键在于:base64编码会让文件体积膨胀约33%,大体积视频转base64后生成的字符串过长,容易触发React Native网络请求的payload大小限制,或是传输过程中出现超时、截断,最终导致"Network request failed"错误。图片和小体积视频能正常上传,也印证了这一点——它们的base64字符串长度在可接受范围内。
可行解决方案
方案1:改用分块上传(推荐)
Supabase Storage支持分块上传,可将大文件拆分成多个小片段依次上传,避免单请求payload过大。结合Expo的FileSystem实现分块读取:
import { supabase } from '../your-supabase-config'; import * as FileSystem from 'expo-file-system'; const uploadVideoToSupabase = async (uri, filePath, mimeType) => { const chunkSize = 5 * 1024 * 1024; // 5MB每块,可根据网络环境调整 const { size: fileSize } = await FileSystem.getInfoAsync(uri); // 初始化分块上传 const { data: uploadData, error: initError } = await supabase.storage .from('files') .createUpload(filePath, fileSize, { contentType: mimeType }); if (initError) throw initError; const { uploadId } = uploadData; // 逐块读取并上传 for (let start = 0; start < fileSize; start += chunkSize) { const end = Math.min(start + chunkSize, fileSize); // 读取当前块的base64内容 const chunk = await FileSystem.readAsStringAsync(uri, { encoding: FileSystem.EncodingType.Base64, position: start, length: end - start, }); const { error: chunkError } = await supabase.storage .from('files') .uploadChunk(uploadId, start, decode(chunk)); if (chunkError) { // 上传失败时取消整个上传任务 await supabase.storage.from('files').cancelUpload(uploadId); throw chunkError; } } // 完成上传流程 const { error: finalError } = await supabase.storage .from('files') .completeUpload(uploadId); if (finalError) throw finalError; console.log('视频上传成功'); };
方案2:优化base64读取与上传参数
如果暂时不想用分块,可尝试调整上传参数:
- 避免手动转ArrayBuffer,直接传入base64字符串并显式指定编码类型:
const { error } = await supabase.storage .from("files") .upload(filePath, base64, { contentType: mimeType, encoding: 'base64' // 显式告知Supabase上传内容为base64编码 }); - 验证文件读取完整性:对比
FileSystem.getInfoAsync获取的文件大小,与base64字符串的计算长度(base64长度≈文件大小*4/3),确认没有读取截断。
方案3:排查环境与限制
- 检查Supabase Storage单文件大小限制(默认最大5GB),确认视频未超出上限;
- 调整网络超时配置,在Supabase客户端初始化时添加全局超时:
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, { global: { fetch: (url, options = {}) => { return fetch(url, { ...options, timeout: 60000 // 设置60秒超时 }); } } }); - 确认React Native/Expo版本无网络请求已知bug,可尝试升级核心包。
已尝试方法的补充说明
- 直接传入DocumentPicker返回的文件:React Native环境下Supabase SDK不支持直接传入本地文件路径,必须转为base64或ArrayBuffer;
- Blob形式上传:React Native的Blob对象实现存在兼容性问题,不推荐用于大文件上传。
内容的提问来源于stack exchange,提问作者timo_omit
相关产品推荐
相关产品推荐

