What I want to do is load different images into ImageView and save them in DB.
My current situation has been successful in obtaining images from albums and cameras, but one image appears in two ImageViews at the same time.
If you look at what's stored in DB, the same picture is stored in two child.
I think the way I think is to give image_url differently, but I don't know if this is a normal way or not.
I'd appreciate it if you could let me know.
add
private void addCoordi() {
//3) add data to db
progressDialog.setMessage("Adding Cody...");
progressDialog.show();
String timestamp = ""+System.currentTimeMillis();
if(image_uri == null ){
//upload without image
//setup data to upload
HashMap<String,Object> hashMap = new HashMap<>();
hashMap.put("codyId",""+timestamp);
hashMap.put("codyTitle",""+coordiTitle);
hashMap.put("codyCategory",""+coordiCategory);
hashMap.put("codyIcon",""); //no image, set empty
hashMap.put("codyIcon2",""); //no image, set empty
hashMap.put("timestamp",""+timestamp);
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
reference.child(firebaseAuth.getUid()).child("Cody").child(timestamp).setValue(hashMap).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
//added to db
progressDialog.dismiss();
Toast.makeText(AdditionCoordiActivity.this,"Cody added...",Toast.LENGTH_SHORT).show();
clearData();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
//failed adding to db
progressDialog.dismiss();
Toast.makeText(AdditionCoordiActivity.this,""+e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
else{
//upload with image
//first upload image to storage
//name and path of image to be uploaded
String filePathAndName = "cody_images/"+""+timestamp;
StorageReference storageReference = FirebaseStorage.getInstance().getReference(filePathAndName);
storageReference.putFile(image_uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//image uploaded
//get url of uploaded image
Task<Uri> uriTask = taskSnapshot.getStorage().getDownloadUrl();
while(!uriTask.isSuccessful());
Uri downloadImageUri = uriTask.getResult();
if(uriTask.isSuccessful()){
//url of image received, upload to db
//setup data to upload
HashMap<String,Object> hashMap = new HashMap<>();
hashMap.put("codyId",""+timestamp);
hashMap.put("codyTitle",""+coordiTitle);
hashMap.put("productCategory",""+coordiCategory);
hashMap.put("codyIcon",""+downloadImageUri); //no image, set empty
hashMap.put("codyIcon2",""+downloadImageUri); //no image, set empty
hashMap.put("timestamp",""+timestamp);
hashMap.put("uid",""+firebaseAuth.getUid());
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
reference.child(firebaseAuth.getUid()).child("Cody").child(timestamp).setValue(hashMap).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
//added to db
progressDialog.dismiss();
Toast.makeText(AdditionCoordiActivity.this,"Cody added...",Toast.LENGTH_SHORT).show();
clearData();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
//failed adding to db
progressDialog.dismiss();
Toast.makeText(AdditionCoordiActivity.this,""+e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
//failed adding to image
progressDialog.dismiss();
Toast.makeText(AdditionCoordiActivity.this, "" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
onActivity
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
if(resultCode == RESULT_OK){
if(requestCode == IMAGE_PICK_GALLEY_CODE){
//image picked from galley
//save pick image uri
image_uri = data.getData();
//set image
productIconIvOne.setImageURI(image_uri);
productIconIvTwo.setImageURI(image_uri);
}else if(requestCode == IMAGE_PICK_CAMERA_CODE){
// image picked from camera
productIconIvOne.setImageURI(image_uri);
productIconIvTwo.setImageURI(image_uri);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
Related
Here i read some input which i want to use for creating "Produs" object which i upload it to the firebase storage, then i want to retrieve it to display a list of objects, i have a problem when i want to update the path to the image storage, to retrieve it later.
public class Add extends AppCompatActivity {
DatabaseReference mDatabase;
EditText etNume, etCantitate, etPret;
Button btnSubmit, btnImage;
Uri mImage;
ImageView ivTest;
public static String path="";
StorageReference mStorageRef;
final int GALLERY_INTENT = 2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
mDatabase = FirebaseDatabase.getInstance().getReference();
etNume = findViewById(R.id.etNume);
etCantitate = findViewById(R.id.etCantitate);
etPret = findViewById(R.id.etPret);
btnSubmit = findViewById(R.id.btnSubmit);
btnImage = findViewById(R.id.btnImage);
ivTest =findViewById(R.id.ivTest);
mStorageRef = FirebaseStorage.getInstance().getReference();
btnImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("image/*");
startActivityForResult(i, GALLERY_INTENT);
}
});
btnSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String nume, pret,cantitate;
nume = etNume.getText().toString().trim();
pret = etPret.getText().toString().trim();
cantitate = etCantitate.getText().toString().trim();
if(TextUtils.isEmpty(nume)){
etNume.setError("Email is required.");
return;
}
if(TextUtils.isEmpty(pret)){
etPret.setError("Email is required.");
return;
}
if(TextUtils.isEmpty(cantitate)){
etCantitate.setError("Email is required.");
return;
}
StorageReference file = mStorageRef.child("Produs").child(nume + ".jpg");
file.putFile(mImage).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
path += taskSnapshot.getMetadata().toString(); /// good path
Toast.makeText(Add.this, path, Toast.LENGTH_SHORT).show();
}
});
Toast.makeText(Add.this, path, Toast.LENGTH_SHORT).show();/// null path
Produs p=new Produs(nume,cantitate,pret,path);
Task task =mDatabase.child("Produs").child(nume).setValue(p);
task.addOnSuccessListener(new OnSuccessListener() {
#Override
public void onSuccess(Object o) {
Toast.makeText(Add.this, "Produsul a fost adaugat cu succes", Toast.LENGTH_SHORT).show();
startActivity(new Intent(getApplicationContext(),MainActivity.class));
}
});
task.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(Add.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == GALLERY_INTENT && resultCode == RESULT_OK && data != null && data.getData() != null){
mImage = data.getData();
ivTest.setImageURI(mImage);
}
}
}
How to have path changed from the onSuccess method?
Basically i want to change the path after i upload an image to build " Produs " object
Also, this is the good path to the image storage? As taskSnapshot.getdownloadURL() doesn't work for me.
The problem is not where you set and read the path variable, the problem is when you do this. Since the getDownloadURL() method makes a call to the server, its onSuccess may run much later than you think.
If you're seeing the wrong value for path, it's very likely that the onSuccess that sets it hasn't run yet. The easiest way to verify that is by either setting breakpoints on the read and write and running in a debugger, or by adding some logging and checking the order of that in your logcat.
The solution for this type of problem is always the same: any code that needs the download URL, needs to either be inside onSuccess, be called from there, or be synchronized in some other way.
So in your case, move the `` into the onSuccess:
StorageReference file = mStorageRef.child("Produs").child(nume + ".jpg");
file.putFile(mImage).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
path += taskSnapshot.getMetadata().toString(); /// good path
Toast.makeText(Add.this, path, Toast.LENGTH_SHORT).show();
Toast.makeText(Add.this, path, Toast.LENGTH_SHORT).show();
Produs p=new Produs(nume,cantitate,pret,path);
Task task =mDatabase.child("Produs").child(nume).setValue(p);
task.addOnSuccessListener(new OnSuccessListener() {
...
});
task.addOnFailureListener(new OnFailureListener() {
...
});
}
});
For more on this, see:
How to store download image url in realtime database firebase android
How to store Url into ArrayList from Firebase Storage?
Can someone help me with logic of the firebase on success listener
getContactsFromFirebase() method return an empty list
Setting Singleton property value in Firebase Listener
Not all of these are directly about Cloud Storage for Firebase, but the explanation applies here as well.
I want to save image url in real-time database but none of the solutions that I tried is solve the problem, the code that I wrote it saving the image in firebase storage but I want to save the image url in real-time database, so can anyone help?
this code just save the image in firebase storage
private Button btn_upload,btn_choose;
private ImageView imageView;
private Uri filepath;
private FirebaseStorage storage;
private StorageReference storageReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_choose= (Button) findViewById(R.id.btn_choose);
btn_upload= (Button) findViewById(R.id.btn_upload);
imageView= (ImageView) findViewById(R.id.myImage);
storage = FirebaseStorage.getInstance();
storageReference = storage.getReference();
btn_upload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
uploadImage();
}
});
btn_choose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
chooseImage();
}
});
}
// choose image function code
private void uploadImage() {
if(filepath!=null) {
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Uploading...");
progressDialog.show();
StorageReference reference = storageReference.child("images/" + UUID.randomUUID().toString());
reference.putFile(filepath).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
progressDialog.dismiss();
Toast.makeText(MainActivity.this, "Image uploaded", Toast.LENGTH_SHORT) .show();
}
})
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progres = (100.0*taskSnapshot.getBytesTransferred()/taskSnapshot.getTotalByteCount());
progressDialog.setMessage("Uploaded"+(int)progres+"%");
}
}) ;
} }
I want to store image in real-time database
You can request download URL for the file after uploading finishes.
Then Add the URL to Real-time Database
reference.putFile(filepath).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
progressDialog.dismiss();
Toast.makeText(MainActivity.this, "Image uploaded", Toast.LENGTH_SHORT) .show();
reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
//You will get donwload URL in uri
Log.d(TAG, "Download URL = "+ uri.toString());
//Adding that URL to Realtime database
mDatabase.child("imageUrl").setValue(uri.toString());
}
});
}
})
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK
&& data != null && data.getData() != null )
{
filePath = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView.setImageBitmap(bitmap);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
private void uploadImage() {
name = txtname.getText().toString();
if(filePath != null)
{
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Uploading...");
progressDialog.show();
StorageReference ref = storageReference.child("images/"+ name);
ref.putFile(filePath)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
progressDialog.dismiss();
Toast.makeText(MainActivity.this, "Uploaded", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(MainActivity.this, "Failed "+e.getMessage(), Toast.LENGTH_SHORT).show();
}
})
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0*taskSnapshot.getBytesTransferred()/taskSnapshot
.getTotalByteCount());
progressDialog.setMessage("Uploaded "+(int)progress+"%");
}
});
}
Toast.makeText(this, name, Toast.LENGTH_SHORT).show();
}
I'm trying to upload some images to firestore storage and put the image URL to firebase database. The images are uploading successfully but the image URLs aren't being added to the database. The problem that I think might be causing this is that the image URL is being added to the Hashmap after uploading the image but the database upload process isn't waiting for the URL instead, adding all other HashMap keys to the database before the Upload task returns the URL. This way all other keys get added to the database but not the Image URLs. In the below code product id is being added successfully to the database, also if I leave any image unselected its url alse gets added as empty to the database which is working fine but if I select an image to upload, The hashmap to database upload finishes even before getting the uploaded image URL.
public class AddProductDataActivity extends AppCompatActivity {
String productId;
EditText productIdEditText;
ImageView addProductImage3;
Button addProductSubmit;
final int IMAGE3_REQUEST = 30;
Uri image3LocationPath;
StorageReference objectStorageReference;
FirebaseFirestore objectFireBaseFireStore;
Map<String, String> objectMap = new HashMap<>();
StorageReference img3Store;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_product_data);
brandNameEditText =(EditText)
addProductImage3 = (ImageView) findViewById(R.id.add_product_image3);
objectStorageReference =
FirebaseStorage.getInstance().getReference("images");
objectFireBaseFireStore = FirebaseFirestore.getInstance();
addProductImage3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent objectIntent = new Intent();
objectIntent.setType("image/*");
objectIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(objectIntent, IMAGE3_REQUEST);
}
});
addProductSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
productId = productIdEditText.getText().toString();
if(image3LocationPath != null)
{
final String image3Name = productId + "_image3." + getExtension(image3LocationPath);
img3Store = objectStorageReference.child(image3Name);
UploadTask imageUploadTask = img3Store.putFile(image3LocationPath);
imageUploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if(!task.isSuccessful())
{
Toast.makeText(AddProductDataActivity.this, "Task Unsuccessful", Toast.LENGTH_SHORT).show();
}
return img3Store.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if(task.isSuccessful())
{
String image_3_url = task.getResult().toString();
objectMap.put("image3_url",image_3_url);
}
else
{
Toast.makeText(AddProductDataActivity.this, task.getException().toString(), Toast.LENGTH_SHORT).show();
}
}
});
}
else
{
objectMap.put("image3_url","");
}
objectFireBaseFireStore.collection("images").document(productId).set(objectMap).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(AddProductDataActivity.this, "Product Added Successfully.", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(AddProductDataActivity.this, "Error in Adding Product. Please Try Again.\n"+e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case 30:
try
{
if(resultCode == RESULT_OK && data != null && data.getData() != null)
{
image3LocationPath = data.getData();
Bitmap objectBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), image3LocationPath);
addProductImage3.setImageBitmap(objectBitmap);
}
}
catch (Exception e)
{
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
private String getExtension(Uri uri){
try
{
ContentResolver objectContentResolver = getContentResolver();
MimeTypeMap objectMimeTypeMap = MimeTypeMap.getSingleton();
return objectMimeTypeMap.getExtensionFromMimeType(objectContentResolver.getType(uri));
}
catch (Exception e)
{
Toast.makeText(AddProductDataActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
return null;
}
}
}
Your code
objectFireBaseFireStore.collection("images").document(productId).set(objectMap)
executes before
objectMap.put("image3_url",image_3_url)
Which means when you are setting your url, your objectMap does not have the key image3_url
Try to set values to database inside onComplete() or use different workaround to set only the url.
You forgot to add your HashMap to Database Reference of Firebase.
This is reference from my current project code.
private void uploadVideo() {
StorageReference mStorageRef = FirebaseStorage.getInstance().getReference();
final StorageReference riversRef = mStorageRef.child(Constants.STORAGE_PATH + "/" + mFinalUploadUri.getLastPathSegment());
riversRef.putFile(mFinalUploadUri).continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw Objects.requireNonNull(task.getException());
}
// Continue with the task to get the download URL
return riversRef.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
FirebaseFirestore database = FirebaseFirestore.getInstance();
String mSelectedCategory = binding.categorySpinner.getSelectedItem().toString();
DocumentReference newDocumentReference = database.collection(PENDING_PATH).document();
VideoModel videoModel = new VideoModel();
videoModel.setDocumentId(newDocumentReference.getId());
videoModel.setTitle(mTitle);
videoModel.setCategory(mSelectedCategory);
//videoModel.setTime(FieldValue.serverTimestamp());
videoModel.setUrl(downloadUri != null ? downloadUri.toString() : null);
newDocumentReference.set(videoModel).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
binding.progressBar.setVisibility(View.GONE);
binding.button.setVisibility(View.VISIBLE);
binding.videoView.setVisibility(View.GONE);
selectedUri = null;
Toast.makeText(AdminVideoUploadActivity.this, R.string.uploaded_successfully, Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(AdminVideoUploadActivity.this, R.string.failed_to_upload, Toast.LENGTH_SHORT).show();
}
});
}
}
});
}
Now you can check code and find where you have done mistake. Just add lines of code of inserting in database.
Thank you.
I have problem to pass the Captured Image to the FilePathUri where the image will be stored and then uploaded to Firebase. I need to integrate them together cause the FilePathUri is always returning null.
Hope somebody can show me an Example with Code. Thanks
On-Create Method
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_takephoto);
// Assign FirebaseStorage instance to storageReference.
storageReference = FirebaseStorage.getInstance().getReference();
// Assign FirebaseDatabase instance with root database name.
databaseReference = FirebaseDatabase.getInstance().getReference(Database_Path);
//Assign ID'S to button.
ChooseButton = (Button)findViewById(R.id.ButtonChooseImage);
UploadButton = (Button)findViewById(R.id.ButtonUploadImage);
// Assign ID's to EditText.
ImageName = (EditText)findViewById(R.id.ImageNameEditText);
// Assign ID'S to image view.
SelectImage = (ImageView)findViewById(R.id.ShowImageView);
// Assigning Id to ProgressDialog.
progressDialog = new ProgressDialog(PhotoActivity.this);
// Adding click listener to Choose image button.
ChooseButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, FilePathUri);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
});
OnActivity
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
// Line 1:
FilePathUri = data.getData();
// Line 2:
Bitmap photo = (Bitmap) data.getExtras().get("data");
SelectImage.setImageBitmap(photo);
ChooseButton.setText("Image Selected");
}
}
Uploading Image Part
// Creating UploadImageFileToFirebaseStorage method to upload image on storage.
public void UploadImageFileToFirebaseStorage() {
// Checking whether FilePathUri Is empty or not.
if (FilePathUri != null) {
// Setting progressDialog Title.
progressDialog.setTitle("Image is Uploading...");
// Showing progressDialog.
progressDialog.show();
// Creating second StorageReference.
StorageReference storageReference2nd = storageReference.child(Storage_Path + System.currentTimeMillis() + "." + FilePathUri);
// Adding addOnSuccessListener to second StorageReference.
storageReference2nd.putFile(FilePathUri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// Getting image name from EditText and store into string variable.
String TempImageName = ImageName.getText().toString().trim();
// Hiding the progressDialog after done uploading.
progressDialog.dismiss();
// Showing toast message after done uploading.
Toast.makeText(getApplicationContext(), "Image Uploaded Successfully ", Toast.LENGTH_LONG).show();
#SuppressWarnings("VisibleForTests")
ImageUploadInfo imageUploadInfo = new ImageUploadInfo(TempImageName, taskSnapshot.getDownloadUrl().toString());
// Getting image upload ID.
String ImageUploadId = databaseReference.push().getKey();
// Adding image upload id s child element into databaseReference.
databaseReference.child(ImageUploadId).setValue(imageUploadInfo);
}
})
// If something goes wrong .
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Hiding the progressDialog.
progressDialog.dismiss();
// Showing exception erro message.
Toast.makeText(PhotoActivity.this, exception.getMessage(), Toast.LENGTH_LONG).show();
}
})
// On progress change upload time.
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
// Setting progressDialog Title.
progressDialog.setTitle("Image is Uploading...");
}
});
}
else {
Toast.makeText(PhotoActivity.this, "Please Select Image or Add Image Name", Toast.LENGTH_LONG).show();
}
I am allowing users to take pictures and store them to Firebase. Below is my code that contains the intent to load the camera application, save the image, and then upload to the Firebase storage. The problem I am having is each subsequent upload to the Firebase Storage is overriding the previous upload, meaning I have 1 file in storage that keeps being overridden. I want to keep adding multiple files:
private void createAlertDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.add_image_dialog_title);
builder.setItems(new CharSequence[]
{getResources().getString(R.string.add_image_web), getResources().getString(R.string.add_image_camera), getResources().getString(R.string.add_image_gallery)},
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// The 'which' argument contains the index position
// of the selected item
switch (which) {
case 0:
Intent toImageSearch = new Intent(CreateActivity.this, NewImageActivity.class);
startActivityForResult(toImageSearch, USE_WEB);
break;
case 1:
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getApplication().getPackageManager()) != null) {
startActivityForResult(takePictureIntent, TAKE_PICTURE);
} else {
Toast.makeText(getApplicationContext(), getResources().getString(R.string.camera_error), Toast.LENGTH_LONG).show();
}
break;
case 2:
Toast.makeText(getApplicationContext(), "clicked 2", Toast.LENGTH_LONG).show();
break;
case 3:
Toast.makeText(getApplicationContext(), "clicked 3", Toast.LENGTH_LONG).show();
break;
}
}
}
);
builder.create().
show();
}
OnActivityResult()
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case USE_WEB:
if (resultCode == CreateActivity.RESULT_OK) {
resultImageURL = data.getStringExtra("result");
mAddImageButton.setVisibility(View.INVISIBLE);
Picasso.with(getApplicationContext())
.load(resultImageURL)
.into(mImagePreview);
}
if (resultCode == CreateActivity.RESULT_CANCELED) {
//Write your code if there's no result
}
case TAKE_PICTURE:
if (resultCode == CreateActivity.RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
mImagePreview.setImageBitmap(imageBitmap);
encodeBitmapAndSaveToFirebase(imageBitmap);
}
}
}
Save to Firebase:
private void encodeBitmapAndSaveToFirebase(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = mPollImageStorage.putBytes(data);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Toast.makeText(getApplicationContext(), "Error Loading Photo", Toast.LENGTH_LONG).show();
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// taskSnapshot.getMetadata() contains file metadata such as size, content-type, and download URL.
Uri downloadUrl = taskSnapshot.getDownloadUrl();
mAddImageButton.setVisibility(View.INVISIBLE);
resultImageURL = downloadUrl.toString();
Picasso.with(getApplicationContext())
.load(resultImageURL)
.into(mImagePreview);
}
});
}
You need to use a separate location or separate file name for each upload.
You can create a custom location like this:
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReferenceFromUrl("gs://myfirebaseproject.appspot.com");
StorageReference fileRef =
storageRef.child(channelId)
.child(String.valueOf(message.getSender()))
.child(String.valueOf(message.getTimestamp()));
UploadTask uploadTask = fileRef.putFile(message.getAttachmentUri());
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
sendMessage(channelId, message.getMessageText(), taskSnapshot.getStorage().toString(), message.getAttachmentType(), callback);
}
});
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
callback.onError(e.toString());
}
});
You can see we are adding custom locations to our base storage reference so that we don't overwrite existing items.
The location that you store your image is determined by what mPollImageStorage is referencing. If mPollingStorage always references the same place, ie, in your onCreate you do something like:
StorageReference mPollingStorage = storageRef.child("polling.jpg");
Then it will keep overriding camerapic.jpg. If you don't want to override it, you could set the image name to something like the time the image was taken or generate a UUID as per this stackoverflow post : Store files with unique/random names