Firebase Duplicates New Uploads On Storage - java

Whenever I make a continuous upload to Firebase, the latest photo that I upload will replace all the other link. it's a weird error and hard to believe.
get result image
String filePath = Environment.getExternalStorageDirectory() + "/image2.jpg";
selectedImageUri = Uri.parse(filePath);
imageView.setImageURI(selectedImageUri);
ImageCompression imageCompression = new ImageCompression(this);
String oath = imageCompression.compressImage(filePath);
uriN = Uri.fromFile(new File(oath));
upload the image
private void fabSend(){
if (uriN!=null){
final StorageReference photoRef = storageRef.child(selectedImageUri.getLastPathSegment() + ".jpg");
photoRef.putFile(uriN).addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();
image = (downloadUrl.toString());
postRef.push().setValue(new myAdapter(image,
description ,
user.getDisplayName())).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
progress.setVisibility(View.GONE);
imageView.setImageBitmap(null);
uriN = null;
fab.setVisibility(View.VISIBLE);
}
});
}
});}
The fact is if I quit the activity and relaunch it again, this does not happen. I have tried using reCreate() but the same happens.
All links are different ie different upload tokens and different images
but the last picture that is uploaded is the one shown for all links.

That's because you're stating that all images must have the same name (image2.jpg) in this line:
String filePath = Environment.getExternalStorageDirectory() + "/image2.jpg";
What you should do instead is get the Uri from the data parameter in onActivityResult() (I assume that's were you're getting the image result:
selectedImageUri = data.getData();
imageView.setImageURI(selectedImageUri);
ImageCompression imageCompression = new ImageCompression(this);
String oath = imageCompression.compressImage(filePath);
uriN = Uri.fromFile(new File(oath));
Edit: You can change the name before sending it to Firebase Storage, maybe adding date and time. Like this:
String newName = new SimpleDateFormat("yyyy-MM-dd-HHmm").format(new Date());
final StorageReference photoRef = storageRef.child("IMG-"+newName+ ".jpg");

Related

How to compress image before upload it to firebase storage?

I want to reduce image file size before I upload it to firebase storage because it take long time to be uploaded.
This is a form which conatins edittext + imageview
I am saving the data(in realtime database) and the image(storage) at the same when clicking on "Save" button.
So how to do to reduce image size or compress it ??
public class PDV_form extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdv_form);
imgproduit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectImage();
}
});
Save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rootNode = FirebaseDatabase.getInstance("https://dtechapp-94795-default-rtdb.europe-west1.firebasedatabase.app");
reference = rootNode.getReference().child("pdv");
String nomcmplt = nomCmplt.getEditText().getText().toString();
String nompdv = nomPdv.getEditText().getText().toString();
String phone = Phone.getEditText().getText().toString();
String adresse = Adresse.getEditText().getText().toString();
String commune = Commune.getEditText().getText().toString();
String wilaya = Wilaya.getEditText().getText().toString();
String codezip = Zip.getEditText().getText().toString();
String email = Email.getEditText().getText().toString();
String imagepdv = placeimgpdv.getDrawable().toString().trim();
UploadDialog = new ProgressDialog(PDV_form.this);
UploadDialog.setTitle("Sauvegarde en cours.... ");
UploadDialog.show();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss", Locale.FRANCE);
Date now = new Date();
String fileName = formatter.format(now);
storageReference = FirebaseStorage.getInstance().getReference("pdv/" + fileName);
storageReference.putFile(imageUri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
placeimgpdv.setImageURI(null);
Toast.makeText(PDV_form.this, "Sauvegarde Terminée", Toast.LENGTH_SHORT).show();
if (UploadDialog.isShowing())
UploadDialog.dismiss();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
if (UploadDialog.isShowing())
UploadDialog.dismiss();
Toast.makeText(PDV_form.this, "Sauvegarde Annulée", Toast.LENGTH_SHORT).show();
}
});
StorageReference filpath = storageReference;
filpath.putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Task<Uri> downloadurl = taskSnapshot.getStorage().getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull #NotNull Task<Uri> task) {
String t = task.getResult().toString();
DatabaseReference newPost = reference.child(nomcmplt + "(" + nompdv + ")");
newPost.child("nomcmplt").setValue(nomcmplt);
newPost.child("nompdv").setValue(nompdv);
newPost.child("phone").setValue(phone);
newPost.child("adresse").setValue(adresse);
newPost.child("commune").setValue(commune);
newPost.child("wilaya").setValue(wilaya);
newPost.child("codezip").setValue(codezip);
newPost.child("email").setValue(email);
newPost.child("imagepdv").setValue(task.getResult().toString());
newPost.child("user_id").setValue(uid);
if (task.isSuccessful()) {
startActivity(new Intent(PDV_form.this, Bottom_bar.class));
}
}
});
}
});
}
});
}
private void selectImage() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
// intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(intent, Gallery_code);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Gallery_code && resultCode == RESULT_OK) {
imageUri = data.getData();
placeimgpdv.setImageURI(imageUri);
}
}
}
You are asking two questions, one is to reduce the size of the image and the other is to compress it. I am assuming you meant to compress the image in a lossy sort of way by reducing the size and not zip it. Let me know if that is not what you meant in the comments.
One option you have is to build a solution manually. Python has a bunch of good libraries that can help you do this, for java, I did find a few good resources that work along this direction, this SO question seems to be pretty good - How can I compress images using java?
Another option is to use a SaaS tool. This would really simplify the process for you and for something as simple as this, it probably won't even cost anything unless you are compressing a lot of images, or really really large images. As a starting point, you can check out TinyPNG - https://tinypng.com/. They have a developer API - https://tinypng.com/developers.
Edit: Based on new information regarding volume, updating my answer.
Since you are expecting a low amount of images, you can just use TinyPNG. It is pretty simple to get started. You can just sign up, and you get an API key. They have a nice API that you can use in Java - https://tinypng.com/developers/reference/java
I am trying to solve this as well and it appears nothing else is directly helpful to our situation.
The "Possible Duplicate" examples only works if you convert your image to a bitmap. Which almost all examples of what you are trying to achieve do so with bitmaps. Here is some code from that "duplicate" that should help you. Though after I implemented this, I had trouble dealing with rotation.
Uri selectedImageUri = data.getData();
Bitmap bmp = null;
try {
bmp = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedImageUri);
} catch (IOException e) {
e.printStackTrace();
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//here you can choose quality factor in third parameter(ex. i choosen 25)
bmp.compress(Bitmap.CompressFormat.JPEG, 25, baos);
byte[] fileInBytes = baos.toByteArray();
StorageReference photoref = chatPhotosStorageReference.child(selectedImageUri.getLastPathSegment());
//here i am uploading
photoref.putBytes(fileInBytes).addOnSuccessListener....etc
Now while this is probably the correct answer. I myself would prefer a cleaner solution that allows me to compress the file via both an InputStream or a Uri, as that is how I upload images to firebase storage as well.
I might be doing the same and dealing with the bitmap directly, but I intend to search for an alternative solution if I can.
To add there is this extension with firebase which will resize after you upload

getExternalStoragePublicDirectory is deprecated counterparts for files that are not mime types

I'm new to development and I faced such a problem, I need to find the file in the downloads folder, since getExternalStoragePublicDirectory is deprecated I read that now it is better to use instead:
1. Context # getExternalFilesDir (String)
2. MediaStore
3. Intent # ACTION_OPEN_DOCUMENT
I tried using the first method to get a list of all documents in the Downloads folder
File file = mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
File[] files = file.listFiles();
int length = files.length;
but length is always 0, although there are files in this folder.
I also cannot use the second method because MediaStore uses a mime type, but my file is not a mime type, since its extension is .gpx
Maybe someone can tell me how to solve this problem
File downloading:
private void mapOptions()
{
bottomSheetDialog = new BottomSheetDialog(mContext);
bottomSheetDialog.setContentView(R.layout.bootom_map_menu);
LinearLayout open = bottomSheetDialog.findViewById(R.id.open_map_bottom_menu);
LinearLayout download = bottomSheetDialog.findViewById(R.id.download_map_bottom_menu);
open.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
download.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DownloadManager downloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(mapUri);
request.setDescription("Downloading...");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
String strPath = mapUri.getPath().toString();
File file = new File(strPath);
filename = file.getName() + ".gpx";
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
request.setRequiresCharging(false);
request.setAllowedOverMetered(true);
request.setAllowedOverRoaming(true);
downloadID = downloadManager.enqueue(request);
bottomSheetDialog.dismiss();
}
});
bottomSheetDialog.show();
}
BroadcastReceiver:
private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if (downloadID == id) {
DownloadManager dm = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = dm.getUriForDownloadedFile(downloadID);
Log.i("Uri result", "Uri to file:" + uri.getPath().toString());
}
}
};

Get images from firebase storage and realtime database

So, I wanna make the user upload multiple images at the same time to firebase storage. I have done that part successfully but now I want to retrieve the images back. At first, I was uploading one image per user and save the image id to the realtime database so it was very easy to retrieve the image back by the image id. But now how can I save more than one image to the realtime database per user I can't use the same child name because it will be replaced with the old one. Any ideas??
Uploding images and setting the id on realtime database:
private void Fileuploader() throws FileNotFoundException {
String imageid;
progress.showProgress(profuctadd.this,"Loading...",false);
DatabaseHelper databaseHelper = new DatabaseHelper(profuctadd.this);
Cursor getimage = databaseHelper.GetPath();
int count = 0;
while (getimage.moveToNext()){
Bitmap bm = BitmapFactory.decodeFile(getimage.getString(0));
ByteArrayOutputStream out = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 35, out);
imageid = arabic.getText().toString()+"-"+System.currentTimeMillis()+"_"+(count++)+"."+getExtension(uri);
System.out.println("IMAGES UPLOADEDDDD: "+ imageid);
String id = getIntent().getStringExtra("storeid");
member.setImageid(imageid);
reference.child(id).child(arname).setValue(member);
byte[] data = out.toByteArray();
StorageReference Ref = mStorageRef.child(imageid);
Ref.putBytes(data)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// Get a URL to the uploaded content
//Uri downloadUrl = taskSnapshot.getDownloadUrl();
//Toast.makeText(profuctadd.this,"Image uploaded",Toast.LENGTH_LONG).show();
progress.hideProgress();
Intent intent = new Intent(profuctadd.this,showProducts.class);
intent.putExtra("spec",getIntent().getStringExtra("spec"));
intent.putExtra("storeid",getIntent().getStringExtra("storeid"));
startActivity(intent);
DatabaseHelper mDatabaseHelper = new DatabaseHelper(profuctadd.this);
Cursor cursor2 = mDatabaseHelper.DeleteDataOfTableImagesAr();
cursor2.moveToNext();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
// ...
Toast.makeText(profuctadd.this,"Failed",Toast.LENGTH_LONG).show();
}
});
}
}
My firebase db:
you can save more than one image of specific user in images node like that.
DatabaseReference dr = FirebaseDatabase.getInstance().getReference("tL131);
dr.child("images").push().setValue(String.ValueOf(taskSnapshot.getDownloadUrl()));

Firebase Content - How to access taskSnapshot.getDownloadUrl() from outside the onSuccess() method

I am currently using Firebase to upload an image into Firebase content in Android Studio. Once the file has successfully uploaded, I receive the url of the uploaded image using taskSnapshot.getDownloadUrl(). I want to then put this url in the Firebase Real-time database as a reference. I'm struggling to access the taskSnapshot.getDownloadUrl() from outside the onSuccess() method. Any ideas, please?
I understand that you want to put the uploaded image URL into Firebase Database.
What you can do is, Declare a global variable of type String
private String imageUrl;
Then get the url of image inside onSuccess() method and store in the string
imageUrl = taskSnapshot.getDownloadUrl().toString();
then after the image is uploaded, you have the image URL as string, so just push it to database like this
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference().child("ImageUrl").setValue(imageUrl);
# declare variable like below:
String Storage_Path = "Image_Uploads/";
String Database_Path = "All_Image_Uploads_Database";
# declare firebase storage or real time database variable like below :
StorageReference myrefrence;
DatabaseReference databaseReference;
myrefrence = FirebaseStorage.getInstance().getReference();
databaseReference = FirebaseDatabase.getInstance().getReference(Database_Path);
public void UploadImageFileToFirebaseStorage(Uri FilePathUri) {
// 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 = myrefrence.child(Storage_Path + System.currentTimeMillis() + "." + GetFileExtension(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("",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(MainActivity.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(MainActivity.this, "Please Select Image or Add Image Name", Toast.LENGTH_LONG).show();
}
}
// Creating Method to get the selected image file Extension from File Path URI.
public String GetFileExtension(Uri uri) {
ContentResolver contentResolver = getContentResolver();
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
// Returning the file Extension.`enter code here`
return mimeTypeMap.getExtensionFromMimeType(contentResolver.getType(uri));
}

Upload Image with a Text (connected) to Firebase Storage

I upload an image to Firebase Storage with Android. I have an app which send image immediately after captured a photo.
But I would like to create an app which show a photo in ImageView before sending. I'd like to write some text under the photo and next, upload both of them.
Which tools should I use to do this?
I've Picasso to download from Storage. But I can't manage how to show an ImageView after capturing a photo, next write some text(like name or description) and send it to Firebase.
The second challenge is how to show particular text with this image?
IMAGE <-> TEXT.
In Firebase Storage I don't see some field to store image with a text.
MainActivity.java:
private ProgressDialog mProgress;
private Bitmap bitmap;
private Button mUploadBtn;
private Button mSendBtn;
private EditText mEditText;
private ImageView mImageView;
Uri picUri;
private StorageReference mStorage;
private static final int CAMERA_REQUEST_CODE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mStorage = FirebaseStorage.getInstance().getReference();
mEditText = (EditText) findViewById(R.id.editText);
mSendBtn = (Button) findViewById(R.id.sendBtn);
mUploadBtn = (Button) findViewById(R.id.uploadBtn);
mImageView = (ImageView) findViewById(R.id.imageView);
mProgress = new ProgressDialog(this);
mUploadBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File file=getOutputMediaFile(1);
picUri = Uri.fromFile(file); // create
i.putExtra(MediaStore.EXTRA_OUTPUT,picUri); // set the image file
startActivityForResult(i, CAMERA_REQUEST_CODE);
}
});
}
public void UploadWithText(){
String name = mEditText.getText().toString().trim();
}
/** Create a File for saving an image */
private File getOutputMediaFile(int type){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyApplication");
/**Create the storage directory if it does not exist*/
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
return null;
}
}
/**Create a media file name*/
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == 1){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".png");
} else {
return null;
}
return mediaFile;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK ) {
mProgress.setMessage("Uploading Image...");
mProgress.show();
Uri uri = picUri;
StorageReference filepath = mStorage.child("Photos").child(uri.getLastPathSegment());
filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
mProgress.dismiss();
Uri downloadUri = taskSnapshot.getDownloadUrl();
Picasso.with(MainActivity.this).load(downloadUri).fit().centerCrop().into(mImageView);
Toast.makeText(MainActivity.this, "Uploaded Successfully.", Toast.LENGTH_LONG).show();
}
});
}
}
Maybe there is a way that I can send the image to Firebase Storage but a Text(description) is sending to Database with a Name field(from Firebase Storage) and with this I can recognize which Text belongs to a particular image?
Could somebody help me to resolve this challenge?
Regards
I can only answer broadly, since there's a bit too much code to answer specifically without doing it for you. In general, there are few ways to do this:
Add text to the image file itself, upload the new image with changes made
Store text as an image attribute, upload the file and save attributes elsewhere
You can either store the data in the Realtime Database, or
You can store the data in Storage file metadata (assuming pairs)

Categories