gpt4 book ai didi

Android Firebase 多图上传

转载 作者:太空宇宙 更新时间:2023-11-03 12:46:46 26 4
gpt4 key购买 nike

我正在编写一个应用程序来测试 firebase,用户可以在其中列出带有图片的产品。我在上传时遇到问题,因为虽然图片已存储,但它们未链接到产品(未传递图像数组?)并且 LeakCanary 发出内存不足错误信号。感谢所有帮助和意见。

这是我的产品模型

@IgnoreExtraProperties
public class Product {

public String uid;
public String seller;
public String name;
public String description;
public String city;
public double price = 0.0;
public List<Uri> images = new ArrayList<>();

public Product () {

}

public Product(String uid, String seller, String name, String description, String city, double price, List<Uri> images) {
this.uid = uid;
this.seller = seller;
this.name = name;
this.description = description;
this.city = city;
this.price = price;
this.images = images;
}

// [START post_to_map]
@Exclude
public Map<String, Object> toMap() {
HashMap<String, Object> result = new HashMap<>();
result.put("uid", uid);
result.put("seller", seller);
result.put("name", name);
result.put("description", description);
result.put("city", city);
result.put("price", price);
result.put("images", images);

return result;
}
}

这是我的 AddProductActivity

public class AddProductActivity extends BaseActivity implements AddProductContract.View, View.OnClickListener {

private AddProductContract.Presenter mPresenter;

private Bitmap mBitmap;
private byte[] mByteArray;
private List<String> mPhotos;
private Button mPublishBtn;
private EditText mProductNameField;
private EditText mProductDescriptionField;
private EditText mProductPriceField;
private DatabaseReference mFirebaseDatabase;
private StorageReference mFirebaseStorage;
private StorageTask mUploadTask;
private List<Uri> uploadedImages = new ArrayList<>();
private LinearLayout mLinearLayout;
private ImageButton mImageButton;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (data == null) {
showEmptyImageError();
} else {
mPhotos = (List<String>) data.getSerializableExtra(GalleryActivity.PHOTOS);
}

}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_edit_product_2);

mFirebaseDatabase = FirebaseDatabase.getInstance().getReference();
mFirebaseStorage = FirebaseStorage.getInstance().getReference();

Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);

mToolbar.setTitle(R.string.addItemTextview);

mLinearLayout = (LinearLayout) findViewById(R.id.activity_add_product);
mLinearLayout.setOnClickListener(this);

mImageButton = (ImageButton) findViewById(R.id.imageButton);
mImageButton.setOnClickListener(this);

mPublishBtn = (Button) findViewById(R.id.publishItemBtn);
mPublishBtn.setOnClickListener(this);

mProductNameField = (EditText) findViewById(R.id.productNameField);
mProductDescriptionField = (EditText) findViewById(R.id.productDescriptionField);
mProductPriceField = (EditText) findViewById(R.id.priceField);

// mPresenter = new AddProductPresenter(this);
}

@Override
public void onClick(View view) {
if ((view == mLinearLayout)) {
hideKeyboard();
} else if (view == mImageButton) {
GalleryConfig config = new GalleryConfig.Build()
.limitPickPhoto(8)
.singlePhoto(false)
.hintOfPick("You can pick up to 8 pictures.")
.filterMimeTypes(new String[]{"image/*"})
.build();
GalleryActivity.openActivity(AddProductActivity.this, 2, config);
} else if (view == mPublishBtn) {
final String name = mProductNameField.getText().toString();
final String description = mProductDescriptionField.getText().toString();
final double price = Double.parseDouble(mProductPriceField.getText().toString());
setPublishingEnabled(false);
showErrorToast(getResources().getString(R.string.publishing));
final String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
mFirebaseDatabase.child("users").child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
if (user == null) {
showErrorToast(getResources().getString(R.string.empty_user));
} else {
publishProduct(userId, user.getUsername(), name, description,
user.getCity(), price, mPhotos);
}
setPublishingEnabled(true);
finish();
}

@Override
public void onCancelled(DatabaseError databaseError) {
Log.w("AddProductActivity", "getUser:onCancelled", databaseError.toException());
setPublishingEnabled(true);
}
}
);
}
}


private void setPublishingEnabled(boolean enabled) {
if (enabled) {
mPublishBtn.setVisibility(View.VISIBLE);
} else {
mPublishBtn.setVisibility(View.GONE);
}
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle arrow click here
if (item.getItemId() == android.R.id.home) {
finish();
}

return super.onOptionsItemSelected(item);
}


@Override
public void showEmptyImageError() {
Toast.makeText(getApplicationContext(), R.string.empty_image_error, Toast.LENGTH_SHORT).show();
}

private void publishProduct(String userId, String seller, String name, String description,
String city, double price, List<String> images) {

for (String photo : images) {
Uri file = Uri.fromFile(new File(photo));
StorageReference photoRef = mFirebaseStorage.child("images/" + file.getLastPathSegment());
mUploadTask = photoRef.putFile(file);

mUploadTask.addOnFailureListener(exception -> Log.i("It didn't work", "double check"))
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();
uploadedImages.add(downloadUrl);
}
});
}


String key = mFirebaseDatabase.child("products").push().getKey();
Product product = new Product(userId, seller, name, description, city, price, uploadedImages);
Map<String, Object> productValues = product.toMap();

Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("/products/" + key, productValues);
childUpdates.put("/user-products/" + userId + "/" + key, productValues);

mFirebaseDatabase.updateChildren(childUpdates);
}

//
// private List<Uri> uploadPhotos(List<String> input) {
// images = new ArrayList<>();
// Observable.just(input)
// .map(this::doInBackground)
// .subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
// .doOnSubscribe(this::onPreExecute)
// .subscribe(this::onPostExecute);
// return images;
// }
//
// private void onPreExecute() {
// Log.i("Start time", "SET");
// Toast.makeText(this, R.string.image_formatting_toast, Toast.LENGTH_SHORT).show();
// }
//
// private List<Uri> doInBackground(List<String> photos) {
// for (String photo : mPhotos) {
// Uri file = Uri.fromFile(new File(photo));
// StorageReference photoRef = mFirebaseStorage.child("images/" + file.getLastPathSegment());
// mUploadTask = photoRef.putFile(file);
//
// mUploadTask.addOnFailureListener(exception -> Log.i("It didn't work", "double check"))
// .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
// @Override
// public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// Uri downloadUrl = taskSnapshot.getDownloadUrl();
// images.add(downloadUrl);
// }
// });
// }
// return images;
// }
//
// private void onPostExecute(List<Uri> uriSet) {
// Toast.makeText(this, R.string.product_visibility_toast, Toast.LENGTH_SHORT).show();
// Log.i("End time", "SET");
// }

}

最佳答案

试图了解您的代码流程,我可以看到一件事:

在您的 publishProduct 方法中,您应该将代码(更新 Firebase 中的子项)放入 addOnSuccessListener,如下所示:

private void publishProduct(String userId, String seller, String name, String description,
String city, double price, List<String> images) {

String key = mFirebaseDatabase.child("products").push().getKey();

for (String photo : images) {
Uri file = Uri.fromFile(new File(photo));
StorageReference photoRef = mFirebaseStorage.child("images/" + file.getLastPathSegment());
mUploadTask = photoRef.putFile(file);

mUploadTask.addOnFailureListener(exception -> Log.i("It didn't work", "double check"))
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();
uploadedImages.add(downloadUrl);

Product product = new Product(userId, seller, name, description, city, price, uploadedImages);
Map<String, Object> productValues = product.toMap();

Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("/products/" + key, productValues);
childUpdates.put("/user-products/" + userId + "/" + key, productValues);

mFirebaseDatabase.updateChildren(childUpdates);
}
});
}

}

而且,如果您想知道 updateChildren 操作是否完成,请添加 onComplete 和 onFailure 监听器,如下所示:

mFirebaseDatabase.updateChildren(childUpdates).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {

}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {

}
});

更新

我认为您可以尝试更改数据库结构,从产品节点中删除图像列表,改为在数据库中添加一个节点,该节点将仅存储与每个产品关联的图像列表:

"/product-images/" + yourKey + "/" + imageKey

包含他的图像列表。 imageKey 与一张图片不同(例如图片名称)。 yourKey 可以是 userId 或与每个产品关联的 key ,这取决于数据库的结构。然后,您可以尝试在 OnSuccessListener 中使用 setValue 而不是 updateChildren,如下所示:

mUploadTask.addOnFailureListener(exception -> Log.i("It didn't work", "double check"))
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();

mFirebaseDatabase.child("product-images").child(yourKey).child(imageKey).setValue(downloadUrl.toString());

}
});

希望这对您有所帮助!

关于Android Firebase 多图上传,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42178298/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com