I am writing an app to test out firebase where a user can list a product with images. I'm having issues with the upload as although the pictures are stored, they are not linked to the product (images array not being passed?) and LeakCanary signals an outofmemory error. All help and input appreciated.
Here's my Product Model
@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;
}
}
And here are is my 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");
// }
}