我制作了一个简单的android应用,将图片上传到Firebase。一切正常,图像成功上传到Firebase存储。但是,从firebase提取URL时出现此错误。
发生StorageException。该位置不存在该对象。代码:-13010 Http结果:404
我发现了前面的大多数问题和答案,但它们对我没有用。预先感谢。
package com.pk.hotandcool.activities;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.fxn.pix.Options;
import com.fxn.pix.Pix;
import com.fxn.utility.ImageQuality;
import com.fxn.utility.PermUtil;
import com.google.android.gms.tasks.Continuation;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageMetadata;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import com.pk.hotandcool.R;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.ArrayList;
public class Test extends AppCompatActivity {
private static final String TAG = "Test";
private RecyclerView recyclerView;
private MyAdapter myAdapter;
private Options options;
private ArrayList<String> returnValue = new ArrayList<>();
private GridLayoutManager gridLayoutManager;
int imageCount = 0;
private FirebaseAuth mAuth;
private String currentUid;
private DatabaseReference userMediaDb;
private StorageReference filePath;
private StorageMetadata metadata;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_media);
initViews();
initFirebase();
recyclerView.setLayoutManager(gridLayoutManager);
myAdapter = new MyAdapter(this);
options = Options.init()
.setRequestCode(100)
.setCount(9)
.setFrontfacing(false)
.setImageQuality(ImageQuality.LOW)
.setPreSelectedUrls(returnValue)
.setScreenOrientation(Options.SCREEN_ORIENTATION_PORTRAIT)
.setPath("DCIM/pk");
recyclerView.setAdapter(myAdapter);
findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
options.setPreSelectedUrls(returnValue);
Pix.start(Test.this, options);
}
});
}
private void initFirebase() {
currentUid = FirebaseAuth.getInstance().getCurrentUser().getUid();
userMediaDb = FirebaseDatabase.getInstance().getReference().child("Users")
.child(currentUid)
.child("media");
}
private void initViews() {
recyclerView = findViewById(R.id.recyclerView);
gridLayoutManager = new GridLayoutManager(this, 3);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100) {
if (resultCode == Activity.RESULT_OK) {
returnValue = data.getStringArrayListExtra(Pix.IMAGE_RESULTS);
if (returnValue != null) {
myAdapter.addImages(returnValue);
if (returnValue.size() > 0) {
uploadMediaToFirebase(returnValue);
}
}
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NotNull String[] permissions, @NotNull int[] grantResults) {
if (requestCode == PermUtil.REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS) {// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Pix.start(Test.this, options);
} else {
Toast.makeText(Test.this, "Approve permissions to open Pix ImagePicker", Toast.LENGTH_LONG).show();
}
return;
}
}
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<String> list = new ArrayList<>();
private Context context;
MyAdapter(Context context) {
this.context = context;
}
void addImages(ArrayList<String> list) {
this.list.clear();
this.list.addAll(list);
notifyDataSetChanged();
}
@NotNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).
inflate(R.layout.pix_image_layout, parent, false);
return new Holder(v);
}
@Override
public void onBindViewHolder(@NotNull RecyclerView.ViewHolder holder, int position) {
File f = new File(list.get(position));
Bitmap d = new BitmapDrawable(context.getResources(), f.getAbsolutePath()).getBitmap();
((Holder) holder).iv.setImageBitmap(d);
}
@Override
public int getItemCount() {
return list.size();
}
class Holder extends RecyclerView.ViewHolder {
ImageView iv;
Holder(View itemView) {
super(itemView);
iv = itemView.findViewById(R.id.iv);
}
}
}
private void uploadMediaToFirebase(ArrayList<String> images) {
filePath = FirebaseStorage.getInstance().getReference()
.child("users")
.child(currentUid)
.child("media");
metadata = new StorageMetadata.Builder()
.setContentType("image/jpg")
.build();
for (int i = 0; i < images.size(); i++) {
String image = images.get(i);
final File file = new File(image);
uploadImages(filePath, metadata, file);
}
}
private void uploadImages(final StorageReference filePath, StorageMetadata metadata, File file) {
UploadTask uploadTask = filePath.child(file.getName()).putFile(Uri.fromFile(file), metadata);
uploadTask.addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
@Override
public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()) {
Log.d(TAG, "onComplete: uploaded successfully" + task.getResult().toString());
} else {
Log.d(TAG, "onComplete: upload failed" + task.getResult().toString());
}
}
});
Task<Uri> task = uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
@Override
public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
Log.d(TAG, "then: " + task.getResult());
if (task.getException() != null)
throw task.getException();
}
Log.d(TAG, "then: " + filePath.getDownloadUrl().toString());
return filePath.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
@Override
public void onComplete(@NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
Log.d(TAG, "onComplete: download uri" + downloadUri.toString());
} else {
if (task.getException() != null)
Log.e(TAG, "onComplete: getting url failed");
Log.d(TAG, "onComplete: download url : " + task.getResult());
task.getException().printStackTrace();
}
}
});
}
}
在您的uploadImages()函数中,您正在使用file.getName(),因此它可能会为不同的文件返回相同的值,并且您的数据将在Firebase中被覆盖。这会引起您遇到的StorageException。消除此异常的一种方法是,您可以为每个文件使用一些唯一的路径。例如,您可以使用timestamp的值(每次上传文件时该值都是唯一的)。
我犯了一个错误,我返回task.getDownloadUrl()而不是reference.getDownloadUrl,所以我更改了这一行
UploadTask uploadTask = filePath.child(file.getName()).putFile(Uri.fromFile(file), metadata);
进入
StorageReference reference = filePath.child(file.getName());
UploadTask uploadTask = reference.putFile(Uri.fromFile(file), metadata);
并返回
return filePath.getDownloadUrl();