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

Android Studio中Firebase多图上传问题:下载URL重复

解决Firebase上传多张图片时URL重复的问题

嘿,我一眼就看出问题所在了——你的代码里只真正上传了第一张图片,另外两张连Firebase Storage都没传进去,最后还把第一张的下载URL重复赋值给了三个字段,自然第二、三张的URL和第一张一模一样。下面我给你修正代码,同时解释关键的修改点:

问题根源分析

  1. 在startPosting()方法中,你只执行了第一张图片的上传操作filepath.putFile(mImageUri),filepath1和filepath2对应的上传逻辑完全没触发
  2. 你直接把第一张图的downloadurl同时赋值给了image、image1、image2三个数据库字段,导致URL重复
  3. 上传条件只检查了mImageUri != null,没验证另外两张图片的URI是否有效

修正后的完整Java代码

package ke.co.tapeli.tapeli;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseAuth.AuthStateListener;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import ke.co.tapeli.tapeli.Auths.Login;

public class UploadActivity extends AppCompatActivity {
    private ImageButton mSelectImage;
    private ImageButton mSelectImage1;
    private ImageButton mSelectImage2;
    private EditText mPostTitle;
    private EditText mPostDesc;
    private EditText mPostNumber;
    private EditText mPostPass;
    private EditText mPostInfo;
    private EditText mPostSteps;
    private EditText mPostPolice;
    private Button mSubmitBtn;
    private Uri mImageUri = null;
    private Uri mImageUri1 = null;
    private Uri mImageUri2 = null;
    private StorageReference mStorage;
    private DatabaseReference mDatabase;
    private ProgressDialog mProgress;
    private static final int GALLERY_REQUEST = 1;
    private static final int GALLERY_REQUEST2 = 2;
    private static final int GALLERY_REQUEST3 = 3;
    private FirebaseAuth mAuth;
    private AuthStateListener mAuthListner;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_upload);
        mAuth = FirebaseAuth.getInstance();
        mAuthListner = new AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                if(firebaseAuth.getCurrentUser() == null){
                    Intent loginIntent = new Intent(UploadActivity.this, Login.class);
                    loginIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(loginIntent);
                }
            }
        };
        mStorage = FirebaseStorage.getInstance().getReference();
        mDatabase = FirebaseDatabase.getInstance().getReference().child("Matapeli");
        mSelectImage = findViewById(R.id.imageSelect);
        mSelectImage1 = findViewById(R.id.imageSelect1);
        mSelectImage2 = findViewById(R.id.imageSelect2);
        mPostTitle = findViewById(R.id.titleField);
        mPostDesc = findViewById(R.id.descField);
        mPostNumber = findViewById(R.id.phoneField);
        mPostPass = findViewById(R.id.passField);
        mPostInfo = findViewById(R.id.otherField);
        mPostSteps = findViewById(R.id.stepsField);
        mPostPolice = findViewById(R.id.policeField);
        mProgress = new ProgressDialog(this);
        mSubmitBtn = findViewById(R.id.submitBtn);

        mSelectImage.setOnClickListener(view -> {
            Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
            galleryIntent.setType("image/*");
            startActivityForResult(galleryIntent, GALLERY_REQUEST);
        });

        mSelectImage1.setOnClickListener(view -> {
            Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
            galleryIntent.setType("image/*");
            startActivityForResult(galleryIntent, GALLERY_REQUEST2);
        });

        mSelectImage2.setOnClickListener(view -> {
            Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
            galleryIntent.setType("image/*");
            startActivityForResult(galleryIntent, GALLERY_REQUEST3);
        });

        mSubmitBtn.setOnClickListener(view -> startPosting());
    }

    private void startPosting() {
        mProgress.setMessage("Adding a Tapeli...");
        final String title_val = mPostTitle.getText().toString().trim();
        final String desc_val = mPostDesc.getText().toString().trim();
        final String namba_val = mPostNumber.getText().toString().trim();
        final String pass_val = mPostPass.getText().toString().trim();
        final String info_val = mPostInfo.getText().toString().trim();
        final String steps_val = mPostSteps.getText().toString().trim();
        final String police_val = mPostPolice.getText().toString().trim();

        // 检查所有必填字段和图片URI是否有效(如果允许部分图片上传,可调整此判断)
        if(!TextUtils.isEmpty(title_val) && !TextUtils.isEmpty(desc_val) 
                && mImageUri != null && mImageUri1 != null && mImageUri2 != null){
            
            mProgress.show();

            // 分别创建三个图片的上传任务
            StorageReference filepath = mStorage.child("Blog_Images").child(mImageUri.getLastPathSegment());
            StorageReference filepath1 = mStorage.child("Blog_Images").child(mImageUri1.getLastPathSegment());
            StorageReference filepath2 = mStorage.child("Blog_Images").child(mImageUri2.getLastPathSegment());

            Task<Uri> uploadTask1 = filepath.putFile(mImageUri).continueWithTask(task -> {
                if (!task.isSuccessful()) {
                    throw task.getException();
                }
                return filepath.getDownloadUrl();
            });

            Task<Uri> uploadTask2 = filepath1.putFile(mImageUri1).continueWithTask(task -> {
                if (!task.isSuccessful()) {
                    throw task.getException();
                }
                return filepath1.getDownloadUrl();
            });

            Task<Uri> uploadTask3 = filepath2.putFile(mImageUri2).continueWithTask(task -> {
                if (!task.isSuccessful()) {
                    throw task.getException();
                }
                return filepath2.getDownloadUrl();
            });

            // 等待三个上传任务全部完成
            Tasks.whenAll(uploadTask1, uploadTask2, uploadTask3)
                    .addOnCompleteListener(task -> {
                        mProgress.dismiss();
                        if (task.isSuccessful()) {
                            // 获取三张图片各自的下载URL
                            String imageUrl = uploadTask1.getResult().toString();
                            String imageUrl1 = uploadTask2.getResult().toString();
                            String imageUrl2 = uploadTask3.getResult().toString();

                            // 写入数据库
                            DatabaseReference newPost = mDatabase.push();
                            newPost.child("title").setValue(title_val);
                            newPost.child("desc").setValue(desc_val);
                            newPost.child("number").setValue(namba_val);
                            newPost.child("passport").setValue(pass_val);
                            newPost.child("info").setValue(info_val);
                            newPost.child("steps").setValue(steps_val);
                            newPost.child("police").setValue(police_val);
                            newPost.child("image").setValue(imageUrl);
                            newPost.child("image1").setValue(imageUrl1);
                            newPost.child("image2").setValue(imageUrl2);

                            Toast.makeText(UploadActivity.this, "Tapeli added successfully!", Toast.LENGTH_SHORT).show();
                            finish();
                        } else {
                            // 处理上传失败的情况
                            Toast.makeText(UploadActivity.this, "Upload failed: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
                        }
                    });
        } else {
            Toast.makeText(this, "Please fill all required fields and select all images!", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == GALLERY_REQUEST && resultCode == RESULT_OK){
            mImageUri = data.getData();
            mSelectImage.setImageURI(mImageUri);
        }
        if(requestCode == GALLERY_REQUEST2 && resultCode == RESULT_OK){
            mImageUri1 = data.getData();
            mSelectImage1.setImageURI(mImageUri1);
        }
        if(requestCode == GALLERY_REQUEST3 && resultCode == RESULT_OK){
            mImageUri2 = data.getData();
            mSelectImage2.setImageURI(mImageUri2);
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        mAuth.addAuthStateListener(mAuthListner);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if(mAuthListner != null){
            mAuth.removeAuthStateListener(mAuthListner);
        }
    }
}

关键修改说明

  1. 完善上传条件检查:现在会验证三张图片的URI都不为空(如果你的需求允许只上传部分图片,可以修改这个判断逻辑)
  2. 分别启动三张图片的上传任务:用continueWithTask链式调用,在上传完成后直接获取下载URL
  3. 等待所有上传完成再写入数据库:使用Tasks.whenAll()来等待三个异步上传任务全部完成,避免因异步操作导致的URL缺失或重复
  4. 独立赋值URL:将三张图片各自的下载URL分别赋值给image、image1、image2字段
  5. 添加异常处理:处理上传失败的情况,给用户友好的提示
  6. 优化代码风格:把匿名内部类换成Lambda表达式,让代码更简洁(兼容Android API 24+,如果需要兼容更低版本可以改回匿名内部类)

内容的提问来源于stack exchange,提问作者user7810601

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:49:40