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.
Related
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);
}
My requirement is the end-user must be able to upload files into the application from internal or external storage and finally display the name of the file in the page.
Actual result: Now I've fetched the file name from the storage and displayed the name in my page.
Expected Result: The end user must be able to load image or video files from external or internal storage to the application and finally display their name in the page.
But don't have any idea about how to load read the file from storage and store it in a arrayList.
Code for fetching the file name
public class ServiceDetails extends AppCompatActivity {
private Button next, attachment_one;
private ImageButton attach_file;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter_details);
next = findViewById(R.id.submit);
attachment_one = findViewById(R.id.attachmentOne);
attach_file = findViewById(R.id.attachFile);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(ServiceDetails.this, ServiceAddress.class);
startActivity(intent);
}
});
attach_file.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.M &&
checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 10001);
}
new MaterialFilePicker()
.withActivity(ServiceDetails.this)
.withRequestCode(1)
.withFilter(Pattern.compile(".*\\.(mkv|wmv|avi|mpeg|swf|mov|mp4|jpg|jpeg)$"))
.withHiddenFiles(true) // Show hidden files and folders
.start();
}
});
attachment_one.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
attachment_one.setVisibility(View.INVISIBLE);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == RESULT_OK) {
String file_path = data.getStringExtra(FilePickerActivity.RESULT_FILE_PATH);
String file_array[] = file_path.split("/");
String file_name = file_array[file_array.length - 1];
// Do anything with file
if(attachment_one.getText().toString().isEmpty()) {
attachment_one.setVisibility(View.VISIBLE);
attachment_one.setText(file_name);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 10001: {
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(ServiceDetails.this, "Permission granted", Toast.LENGTH_LONG).show();
}else {
Toast.makeText(ServiceDetails.this, "Permission not granted", Toast.LENGTH_LONG).show();
finish();
}
}
}
}
}
I'm new to android and kindly help me providing solution for this answer. Million thanks in advance!
Image showing file attachment option
As you are willing to load the title of video/images, and other file related information from the External Storage. You have to use this code and also make sure don't forget to create a Arraylist with model(required to extract information and find to the listview).
//ContentResolver and contentProvider as well as cursor
String[] projection = new String[]{
MediaStore.Video.Media._ID,
MediaStore.Video.Media.TITLE,
MediaStore.Video.Media.SIZE,
MediaStore.Video.Media.DATE_MODIFIED
};
String selection = null;
String[] selectionargs = null;
String orderBy = MediaStore.Video.Media.DISPLAY_NAME + " Desc";
Uri content_uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = getContentResolver().query(content_uri, projection, selection, selectionargs, orderBy);
if (cursor != null) {
cursor.moveToPosition(0);
}
while (true) {
long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID));
Uri VideoUri = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id);
Log.d("uri", "onCreate: video path " + VideoUri);
String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE));
float size = cursor.getFloat(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE));
// loading a thumbnail from the content resolver
// Load thumbnail of a specific media item.
Bitmap thumbnail = null;
try {
thumbnail = getApplicationContext().getContentResolver().loadThumbnail(VideoUri, new Size(200, 200), null);
Log.d("thumbnail", "onCreate: Lodaing a thumbnail");
} catch (IOException e) {
Log.d("thumbnail", "onCreate: Showing Error on thumbnail");
e.printStackTrace();
}
videolist.add(new Video(thumbnail, VideoUri, title, size));
if (!cursor.isLast()) {
cursor.moveToNext();
} else {
Log.d("lastItem", "onCreate: last uri is encountered");
break;
}
}
cursor.close();
My goal is to add new product, for each product contain picture and pdf file to firebase storage, then save each link to firebase database.
I got a problem went upload a picture and pdf. I cant get download URL from each file and return null went I'm try post to database.
code:
private void bukafilemanager(View view) {
switch (view.getId()){
case R.id.pilih_gambar:
Intent gambar = new Intent();
gambar.setType("image/*");
gambar.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(gambar, PICK_IMAGE_REQUEST);
break;
case R.id.pilih_pdf:
Intent pdf = new Intent();
pdf.setType("application/*");
pdf.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(pdf, PICK_FILE_REQUEST);
}
}
#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){
URI_Image = data.getData();
daftarupload.add(URI_Image);
Glide.with(this).load(URI_Image).into(preview_gambar);
preview_gambar.setImageURI(URI_Image);
} else if (requestCode == PICK_FILE_REQUEST && resultCode == RESULT_OK && data != null && data.getData()!= null){
URI_File = data.getData();
daftarupload.add(URI_File);
}
}
public String getMimeType(Context context, Uri uri) {
String extension;
//Check uri format to avoid null
if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
//If scheme is a content
MimeTypeMap mime = MimeTypeMap.getSingleton();
extension = mime.getExtensionFromMimeType(context.getContentResolver().getType(uri));
} else {
//If scheme is a File
//This will replace white spaces with %20 and also other special characters. This will avoid returning null values on file name with spaces and special characters.
extension = MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(new File(uri.getPath())).toString());
}
return extension;
}
protected void uploadfile(ArrayList<Uri> daftarupload){
progressDialog.setMessage("Harap Tunggu...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setIndeterminate(true);
progressDialog.setProgress(count);
progressDialog.setMax(daftarupload.size());
progressDialog.show();
String nama_produk = namaproduk.getText().toString();
String ket_produk = ketproduk.getText().toString();
if(!TextUtils.isEmpty(nama_produk) && !TextUtils.isEmpty(ket_produk)) {
for (Uri uri : daftarupload) {
switch (getMimeType(getBaseContext(), uri)) {
case "jpg":
final StorageReference lokasijpg = storage.child(id_produk + ".jpg");
lokasijpg
.putFile(uri)
.addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isComplete()){
lokasijpg
.getDownloadUrl()
.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
URL_JPG = uri;
count += 1;
progressDialog.setProgress(count);
}
});
}
}
});
break;
case "pdf":
final StorageReference lokasipdf = storage.child(id_produk + ".pdf");
lokasipdf
.putFile(uri)
.addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if(task.isComplete()){
lokasipdf
.getDownloadUrl()
.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
URL_PDF = uri;
count += 1;
progressDialog.setProgress(count);
}
});
}
}
});
break;
default:
progressDialog.dismiss();
Toast.makeText(getBaseContext(), "Format Tidak Sesuai", Toast.LENGTH_LONG).show();
break;
}
}
simpandata(id_produk, nama_produk, ket_produk , URL_JPG, URL_PDF);
progressDialog.dismiss();
} else {
progressDialog.dismiss();
Toast.makeText(tambahproduk.this,"Semua data harus diisi lengkap!", Toast.LENGTH_LONG).show();
}
}
protected void simpandata(String id_produk, final String nama_produk, String ket_produk, Uri URL_JPG, Uri URL_PDF){
produk produk = new produk(id_produk,nama_produk,ket_produk,URL_JPG.toString(),URL_PDF.toString());
database.child(id_produk).setValue(produk).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
progressDialog.dismiss();
Toast.makeText(tambahproduk.this, "Produk "+nama_produk.toString()+" Berhasil Ditambahkan", Toast.LENGTH_LONG).show();
finish();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(tambahproduk.this, e.toString(), Toast.LENGTH_LONG).show();
}
});
}
error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.user.katalog.lulu.user, PID: 27391
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.toString()' on a null object reference
at com.user.katalog.lulu.user.tambahproduk.simpandata(tambahproduk.java:237)
at com.user.katalog.lulu.user.tambahproduk.uploadfile(tambahproduk.java:226)
at com.user.katalog.lulu.user.tambahproduk$3.onClick(tambahproduk.java:102)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
According to your comment, I understand that you are getting that error because of the following line of code:
produk produk = new produk(id_produk,nama_produk,ket_produk,URL_JPG.toString(),URL_PDF.toString());
It is because you cannot create the URL_PDF varaible as a global variable and expect to work fine. You cannot use something now that hasn't been loaded yet. With other words, you cannot simply use the URL_PDF object outside the onComplete() method because it will always be null due the asynchronous behaviour of this method. This means that by the time you are trying to use that result outside that method, the data hasn't finished loading yet from the database and that's why is not accessible. A quick solve for this problem would be to use the URL_PDF varaible only inside the onComplete() method, otherwise I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.
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