Firebase Storage refFromURL传https链接删文件报404 StorageException异常
Firebase Storage 调用refFromURL传入HTTPS链接报404 NotFound错误
问题现象
- 已实现Firebase Storage照片上传、删除功能,封装的删除方法如下:
Future<void> deleteStorageData({@required String url}) async { final reference = FirebaseStorage.instance.refFromURL(url); await reference.delete(); }
- 传入带签名参数的HTTPS格式文件访问链接调用方法时,抛出如下异常:
E/StorageException( 5079): Object does not exist at location
接口返回404 "NotFound"错误,但该链接可以在浏览器中正常访问并展示对应文件,测试用HTTPS链接格式如下:
https://firebasestorage.googleapis.com/v0/b/masterdetail-t4lf.appspot.com/o/user_image%2F2022-06-15T22%3A08%3A04.308422.jpg?alt=media&token=f80ad36e-1a8b-45d2-86bb-ac1dc14b9991
- 传入gs协议格式的文件存储路径调用方法时,删除操作可正常执行无报错,测试用gs路径格式如下:
gs://masterdetail-t4lf.appspot.com/user_image/2022-06-15T22:08:04.308422.jpg
- 排查定位核心问题:
.refFromURL(url)方法返回的存储引用会在路径中第一个%3A(即冒号:的URL编码结果)位置截断路径,无法定位到完整文件。
根本原因
这是部分旧版本firebase_storage插件存在的解析bug:refFromURL方法处理HTTPS格式的下载链接时,没有正确对路径段做完整URL解码,遇到编码后的特殊字符就会提前截断路径,最终生成的存储引用路径不完整,匹配不到存储桶内的实际文件。
另外需要注意:带alt=media、签名token参数的HTTPS链接是Firebase生成的公网下载访问链接,本身不是SDK识别存储资源的标准定位标识,即使修复了解码bug,后续SDK版本迭代也可能调整这类链接的解析逻辑,不建议直接作为操作存储文件的参数传入。
修复方案
- 方案一(推荐):上传文件后持久化存储gs格式路径
文件上传成功后,直接从返回的引用对象中获取gs路径存入数据库,后续删除、读取等所有文件操作都传入gs路径调用方法即可。gs路径是Firebase Storage的原生资源定位标识,不存在URL编码、签名参数解析问题,全版本SDK兼容性最好。 - 方案二:兼容存量HTTPS链接,手动解析路径生成引用
如果数据库中已经存量保存了大量HTTPS格式链接,不需要全量替换,不要直接把HTTPS链接传入refFromURL,先手动从链接中解析出真实文件路径,再通过ref()方法生成存储引用,示例代码:
Future<void> deleteStorageData({@required String url}) async { final uri = Uri.parse(url); // 提取/o/之后的编码文件路径并解码 final encodedPath = uri.path.split('/o/')[1]; final filePath = Uri.decodeComponent(encodedPath); // 直接通过文件路径生成引用 final reference = FirebaseStorage.instance.ref(filePath); await reference.delete(); }
内容的提问来源于stack exchange,提问作者CEO tech4lifeapps
相关产品推荐
相关产品推荐

