You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase中下载并重传图片遇存储异常,求解决方法

问题描述

我的图片存储在Firebase Storage中,对应的URL存在Realtime Database里,数据结构如下:

Type1
----Time1
--------elements of type1
----Time2
--------elements of type2
Type2
....

我需要允许用户修改元素的时间,所以要把元素从一个Time分支移到另一个分支。目前的实现逻辑是在新分支创建新元素,再删除旧元素,但同步图片的时候出了问题。

我试过用Uri.parse()解析Realtime Database里存的URL,也试过用StorageReference.getDownloadUrl()获取Uri,但都报同样的错误:

could not locate file for uploading:https://firebasestorage.googleapis.com/v0/b/re...
E/StorageException: StorageException has occurred.
    An unknown error occurred, please check the HTTP result code and inner exception for server response.
     Code: -13000 HttpResult: 0

手动点击错误里的链接能正常显示图片,但程序就是找不到文件。我的代码如下:

storageReference = FirebaseStorage.getInstance().getReference().child("images/Anime/General/Test1");
storageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
    @Override
    public void onSuccess(Uri uri) {
        storageReference = FirebaseStorage.getInstance().getReference().child("images/Anime/Future/Test1");
        storageReference.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                ...
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {

            }
        });
    }
});

错误出现在storageReference.putFile(uri)这一行。

问题原因与解决方案

问题原因

putFile()方法的设计是用来上传本地文件/设备内的Uri(比如content://开头的本地资源地址),而你传入的是Firebase Storage生成的HTTPS下载链接,这种网络Uri不在putFile()的支持范围内,所以程序会提示找不到文件。

解决方案

最推荐的方式是直接在Firebase Storage内部复制文件,不需要下载再上传,既高效又避免网络问题:

方法1:使用StorageReference的copyTo()方法

直接获取旧文件的Storage引用,调用copyTo()复制到新路径,完成后更新Realtime Database里的URL,最后删除旧文件即可。示例代码:

// 获取旧文件的Storage引用
StorageReference oldRef = FirebaseStorage.getInstance().getReference().child("images/Anime/General/Test1");
// 定义新文件的Storage引用
StorageReference newRef = FirebaseStorage.getInstance().getReference().child("images/Anime/Future/Test1");

// 执行复制操作
oldRef.copyTo(newRef).addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
    @Override
    public void onSuccess(StorageMetadata storageMetadata) {
        // 复制成功后,获取新文件的下载URL
        newRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
            @Override
            public void onSuccess(Uri newUri) {
                // 更新Realtime Database中对应元素的图片URL
                // ... 这里写更新数据库的逻辑

                // 最后删除旧文件(可选,根据业务需求决定)
                oldRef.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void unused) {
                        // 旧文件删除成功
                    }
                });
            }
        });
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        // 复制失败,处理错误
    }
});

方法2:下载后再上传(不推荐)

如果必须用下载再上传的方式,需要先把网络图片下载到本地存储,得到本地文件的Uri,再调用putFile()上传。这种方式会消耗额外的带宽和时间,仅在特殊场景下使用。

内容的提问来源于stack exchange,提问作者C-Gian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 23:20:38