I am trying to store images into Firebase Storage and then download the URI of those images from Firebase storage and then again upload those URI into the firebase firestore using a foreach loop . Images are successfully uploading into the firebase storage but Uri of only last image is going into firestore first three are failing. I created AN ARRAY LIST OF BITMAPS and then used foreach loop on it.
My Code
private void UploadingImage() {
if (bitmap != null && bitmap2 != null && bitmap3 != null && bitmap4 != null) {
StorageTask arrayUpload;
fuser = FirebaseAuth.getInstance().getCurrentUser();
ProductName = Objects.requireNonNull(Product_Name_EditText.getText()).toString();
CityName = Objects.requireNonNull(CityNameEditText.getText()).toString();
// Bitmap[] bitmaps=new Bitmap[3];
ArrayList<Bitmap> bitmapArrayList = new ArrayList<>();
bitmapArrayList.add(bitmap);
bitmapArrayList.add(bitmap2);
bitmapArrayList.add(bitmap3);
bitmapArrayList.add(bitmap4);
Bitmap bitresized;
for (Bitmap bitUpload : bitmapArrayList)
{
bitresized = Bitmap.createScaledBitmap(bitUpload, 800, 800, true);
ByteArrayOutputStream baosArray = new ByteArrayOutputStream();
bitresized.compress(Bitmap.CompressFormat.JPEG, 70, baosArray);
byte[] uploadbaosarray = baosArray.toByteArray();
i = i + 1;
fileReference = storageReference.child(ProductName).child(i + ProductName + ".jpg");
arrayUpload = fileReference.putBytes(uploadbaosarray);
arrayUpload.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
} else if (task.isSuccessful()) {
Toast.makeText(Upload_New_Product.this, "Uploaded Successfully", Toast.LENGTH_SHORT).show();
//mProgressBar.setVisibility(View.INVISIBLE);
}
return fileReference.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
assert downloadUri != null;
String mUri = downloadUri.toString();
ProductName = Product_Name_EditText.getText().toString();
ProductRef = db.collection("Sellers").document(CityName).collection(Uid).document(ProductName);
HashMap<String, Object> map = new HashMap<>();
map.put("imageURL" + i, mUri);
//reference.updateChildren(map);
ProductRef.set(map, SetOptions.merge());
} else {
Toast.makeText(Upload_New_Product.this, "Failed!", Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(Upload_New_Product.this, e.getMessage(), Toast.LENGTH_SHORT).show();
//pd.dismiss();
}
});
}
}
}
Since uploading (and getting the download URL) are asynchronous operations, the for loop completes almost immediately, and all uploads are happening in parallel after that. This means that by the time your map.put("imageURL" + i, mUri) runs, the i variable is going to be its final value.
To make the code work, you need to capture the variable of i for each iteration over the loop. A simple way to do that, is to move the code that uploads the image and stores its URL into a separate function, and pass the value of i into that function call.
Something like:
public void uploadFileAtIndex(int i) {
fileReference = storageReference.child(ProductName).child(i + ProductName + ".jpg");
arrayUpload = fileReference.putBytes(uploadbaosarray);
arrayUpload.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
} else if (task.isSuccessful()) {
Toast.makeText(Upload_New_Product.this, "Uploaded Successfully", Toast.LENGTH_SHORT).show();
}
return fileReference.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
assert downloadUri != null;
String mUri = downloadUri.toString();
ProductName = Product_Name_EditText.getText().toString();
ProductRef = db.collection("Sellers").document(CityName).collection(Uid).document(ProductName);
HashMap<String, Object> map = new HashMap<>();
map.put("imageURL" + i, mUri);
ProductRef.set(map, SetOptions.merge());
} else {
Toast.makeText(Upload_New_Product.this, "Failed!", Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(Upload_New_Product.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
And then use it in the loop with:
for (Bitmap bitUpload : bitmapArrayList) {
...
i = i + 1;
uploadFileAtIndex(i);
}
You might need to pass more of your variable to uploadFileAtIndex than I've done here, but its passing i that solves the problem you have right now.
Related
I am storing some data into the firebase firestore and using onComplete listener on the operation. I am Storing the ID which I generated, in a String and using it to perform further operations.
ProductRef = db.collection("Sellers").document(CityName).collection(Uid).document();
ProductID =db.collection("Sellers").document(CityName).collection(Uid).document().getId();
I am then using that generated Id to as a field in Cloud Storage and adding some images inside it and after it using the same ID I am storing the URLs of these images in the firestore but what happening is a different Id is generated in between and details are stored inside one Id and ImageUrls inside another.
My code
private void UploadDetails() {
ProductRef = db.collection("Sellers").document(CityName).collection(Uid).document();
ProductID =db.collection("Sellers").document(CityName).collection(Uid).document().getId();
HashMap<String, Object> map = new HashMap<>();
map.put("City_Name", CityName);
ProductRef.set(map, SetOptions.merge()).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
UploadingImage();
UploadingThumbnailImage();
}
});
}
private void UploadingImage() {
resized = Bitmap.createScaledBitmap(bitmap, 800, 800, true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
resized.compress(Bitmap.CompressFormat.JPEG, 70, baos);
byte[] uploadbaos = baos.toByteArray();
ProductRef = db.collection("Sellers").document(CityName).collection(Uid).document(ProductID);
fileReference = storageReference.child(ProductID).child("1" + ProductID + ".jpg");
uploadTask = fileReference.putBytes(uploadbaos);
uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
} else if (task.isSuccessful()) {
Toast.makeText(Upload_New_Product.this, "Uploaded Successfully", Toast.LENGTH_SHORT).show();
//mProgressBar.setVisibility(View.INVISIBLE);
}
return fileReference.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
String mUri = downloadUri.toString();
// ProductRef=db.collection("Sellers").document().collection(ProductType);
ProductName = Product_Name_EditText.getText().toString();
// ProductRef = db.collection("Sellers").document(CityName).collection(Uid).document(ProductID);
//reference = FirebaseDatabase.getInstance().getReference("Users").child(fuser.getUid());
HashMap<String, Object> map = new HashMap<>();
map.put("imageURL", mUri);
//reference.updateChildren(map);
ProductRef.set(map, SetOptions.merge());
//pd.dismiss();
} else {
Toast.makeText(Upload_New_Product.this, "Failed!", Toast.LENGTH_SHORT).show();
//pd.dismiss();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(Upload_New_Product.this, e.getMessage(), Toast.LENGTH_SHORT).show();
//pd.dismiss();
}
});
}
Every time you call document() with no parameters, you're going to get a different random document ID. Your code here is calling document() twice:
ProductRef = db.collection("Sellers").document(CityName).collection(Uid).document();
ProductID = db.collection("Sellers").document(CityName).collection(Uid).document().getId();
If you want a single random ID to reuse, just call it once:
ProductRef = db.collection("Sellers").document(CityName).collection(Uid).document();
ProductID = ProductRef.getId();
I'm creating an app like olx, Where if you upload ad , its gets posted in two different collections, namly "My Ads" where ads of every logged in user are posted against his ID, and Explore collection Where ads are posted for all users. So if i want to update or delete ad, It should be deleted from both collections! Image Url :https://imgur.com/a/HCKfGBb
String uid= user.getUid();
SellingDetails.put("uid",uid);
final CollectionReference reference = exploreAdDB.collection("cities/" + city + "/" + category);
final CollectionReference myAdDocRef = myAdDB.collection("users/ads/"+uid);
if (imageUri != null) {
final StorageReference fileReference = mStorage.child(System.currentTimeMillis()
+ "." + getFileExtension(imageUri));
UploadTask uploadTask = fileReference.putFile(imageUri);
Task<Uri> urlTask = uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
}
return fileReference.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
if(downloadUri!=null)
SellingDetails.put("imageUrl",downloadUri.toString());
reference.add(SellingDetails).addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
Toast.makeText(GetLocationActivity.this, "Service Uploaded in explore db ", Toast.LENGTH_SHORT).show();
pgAd.setVisibility(View.INVISIBLE);
Intent intent = new Intent(GetLocationActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Toast.makeText(GetLocationActivity.this, "Ad posted Successfully", Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(GetLocationActivity.this, "Failed adding data into explore db", Toast.LENGTH_SHORT).show();
pgAd.setVisibility(View.INVISIBLE);
}
});
myAdDocRef.add(SellingDetails).addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
Toast.makeText(GetLocationActivity.this, "Data Also added to myAds db", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(GetLocationActivity.this, "Data not added into my ads", Toast.LENGTH_SHORT).show();
}
});
} else {
// Handle failures
Toast.makeText(GetLocationActivity.this, "Failed adding data", Toast.LENGTH_SHORT).show();
}
}
});
}
How my app adds values to realtime database:
private void uploadFile() {
if(imageUri != null){
final StorageReference fileReference = storageReference.child(System.currentTimeMillis()
+ "." + getFileExtension(imageUri));
storageTask = fileReference.putFile(imageUri);
Task<Uri> urlTask = storageTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
}
// Continue with the task to get the download URL
return fileReference.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
String miUrlOk = downloadUri.toString();
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
final String kisiId = user.getUid().toString().trim();
final String kisiAd = user.getDisplayName().toString().trim();
final String urunIsim = editurunIsim.getText().toString().trim();
final String urunYorum = editUrunYorum.getText().toString();
Map<String,Object> values = new HashMap<String,Object>();
values.put("kisiId", kisiId);
values.put("kisiAd", kisiAd);
values.put("urunAdi", urunIsim);
values.put("yorum", urunYorum);
Kullanici kullanici = new Kullanici(kisiId, kisiAd, urunIsim,urunYorum,miUrlOk);
DatabaseReference dbRef = db.getReference("Kullanici");
String key = dbRef.push().getKey();
DatabaseReference databaseReference = db.getReference("Kullanici/" + key);
databaseReference.setValue(kullanici);
String referansinAnahtari=databaseReference.getKey().toString();
databaseReference.child("urunYorum").child(referansinAnahtari).setValue(values);
Toast.makeText(getActivity(), "Upload successful", Toast.LENGTH_LONG).show();
} else {
// Handle failures
// ...
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}else{
Toast.makeText(getActivity(), "No File selected", Toast.LENGTH_SHORT).show();
}
}
How my app reads values from realtime database (a part):
kullaniciList.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Kullanici kullaniciModel = postSnapshot.getValue(Kullanici.class);
kullaniciModel.setKey(postSnapshot.getKey());
kullaniciList.add(kullaniciModel);
}
adapterr.setOnItemClickListener(anasayfaFragment.this);
adapterr.notifyDataSetChanged();
progressCircle.setVisibility(View.INVISIBLE);
my debug is closed when I run it with debug. I think it's a logic error. How do I capture data from a realtime database?
private void uploadImageToFirebaseStorage() {
StorageReference profileImageRef =
FirebaseStorage.getInstance().getReference("profilepics/" + System.currentTimeMillis() + ".jpg");
if (uriProfileImage != null) {
progressBar.setVisibility(View.VISIBLE);
profileImageRef.putFile(uriProfileImage)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(#NonNull UploadTask.TaskSnapshot taskSnapshot) {
progressBar.setVisibility(View.GONE);
profileImageUrl = taskSnapshot.**getDownloadUrl**().toString();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressBar.setVisibility(View.GONE);
Toast.makeText(ProfileActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
taskSnapshot.getDownloadUrl() method not working comes up with red line under it
Edit: see this comment on why the approach in this answer doesn't work:
firebaser here This answer is wrong. While it at first may appear to work (since it compiles) the result of getDownloadUrl().toString() is not a download URL, but a string representation of a Task object. For a better answer, see stackoverflow.com/a/55503926 or the sample in the Firebase documentation.
Original answer below...
In Firebase Storage API version 16.0.1,
the getDownloadUrl() method using taskSnapshot object has changed.
now you can use,
taskSnapshot.getMetadata().getReference().getDownloadUrl().toString()
to get download url from the firebase storage.
To get imageUrl path from storage use this code:
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
if (taskSnapshot.getMetadata() != null) {
if (taskSnapshot.getMetadata().getReference() != null) {
Task<Uri> result = taskSnapshot.getStorage().getDownloadUrl();
result.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String imageUrl = uri.toString();
//createNewPost(imageUrl);
}
});
}
}
}});
that is all 😉
NOTE: Do not forget initialize StorageReference and UploadTask in your uploadFile method.
Try Using this it will download the image from FireBase storage
FireBase Libraries versions 16.0.1
Task<Uri> result = taskSnapshot.getMetadata().getReference().getDownloadUrl();
result.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String photoStringLink = uri.toString();
}
});
I faced the similar error I solved it with this method. Hope it helps
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Task<Uri> task = taskSnapshot.getMetadata().getReference().getDownloadUrl();
task.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String photoLink = uri.toString();
Map userInfo = new HashMap();
userInfo.put("profileImageUrl", photoLink);
mUserDatabase.updateChildren(userInfo);
}
});
finish();
return;
}
});
ref.putFile(filePath)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
taskSnapshot.getStorage().getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
changeProfilePic(String.valueOf(task.getResult()));//gives image or file string url
}
});
try this code will work for sure
My Google Firebase Plugins in build.gradle(Module: app):
implementation 'com.firebaseui:firebase-ui-database:3.3.1'
implementation 'com.firebaseui:firebase-ui-auth:3.3.1'
implementation 'com.google.firebase:firebase-core:16.0.0'
implementation 'com.google.firebase:firebase-database:16.0.1'
implementation 'com.google.firebase:firebase-auth:16.0.1'
implementation 'com.google.firebase:firebase-storage:16.0.1'
build.gradle(Project):
classpath 'com.google.gms:google-services:3.2.1'
My upload() function and fetching uploaded data from Firebase storage :
private void upload() {
if (filePath!=null) {
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Uploading...");
progressDialog.show();
final StorageReference ref = storageReference.child(new StringBuilder("images/").append(UUID.randomUUID().toString()).toString());
uploadTask = ref.putFile(filePath);
Task<Uri> urlTask = uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
}
return ref.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
progressDialog.dismiss();
// Continue with the task to get the download URL
saveUrlToCategory(downloadUri.toString(),categoryIdSelect);
} else {
Toast.makeText(UploadWallpaper.this, "Fail UPLOAD", Toast.LENGTH_SHORT).show();
}
}
}).addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
progressDialog.setMessage("Uploaded: ");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(UploadWallpaper.this, "" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
FOR THOSE WHO ARE USING LATEST FIREBASE VERSION taskSnapshot.getDownloadUrl() method is DEPRECATED or OBSOLETE !!
I'm using Firebase Storage API version 16.0.5 and the task has to be referenced as
someTask.getResult().getMetadata().getReference().getDownloadUrl().toString();
hope this helps!
You wont get the download url of image now using
profileImageUrl = taskSnapshot.**getDownloadUrl**().toString();
this method is deprecated.
Instead you can use the below method
uniqueId = UUID.randomUUID().toString();
ur_firebase_reference = storageReference.child("user_photos/" + uniqueId);
Uri file = Uri.fromFile(new File(mphotofile.getAbsolutePath()));
UploadTask uploadTask = ur_firebase_reference.putFile(file);
Task<Uri> urlTask = uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
}
// Continue with the task to get the download URL
return ur_firebase_reference.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
System.out.println("Upload " + downloadUri);
Toast.makeText(mActivity, "Successfully uploaded", Toast.LENGTH_SHORT).show();
if (downloadUri != null) {
String photoStringLink = downloadUri.toString(); //YOU WILL GET THE DOWNLOAD URL HERE !!!!
System.out.println("Upload " + photoStringLink);
}
} else {
// Handle failures
// ...
}
}
});
//upload button onClick
public void uploadImage(View view){
openImage()
}
private Uri imageUri;
ProgressDialog pd;
//Call open Image from any onClick Listener
private void openImage() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent,IMAGE_REQUEST);
}
private void uploadImage(){
pd = new ProgressDialog(mContext);
pd.setMessage("Uploading...");
pd.show();
if (imageUri != null){
final StorageReference fileReference = storageReference.child(userID
+ "."+"jpg");
// Get the data from an ImageView as bytes
_profilePicture.setDrawingCacheEnabled(true);
_profilePicture.buildDrawingCache();
//Bitmap bitmap = ((BitmapDrawable) _profilePicture.getDrawable()).getBitmap();
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
} catch (IOException e) {
e.printStackTrace();
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 20, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = fileReference.putBytes(data);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
pd.dismiss();
Log.e("Data Upload: ", "Failled");
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// taskSnapshot.getMetadata() contains file metadata such as size, content-type, etc.
// ...
Log.e("Data Upload: ", "success");
Task<Uri> result = taskSnapshot.getMetadata().getReference().getDownloadUrl();
result.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String downloadLink = uri.toString();
Log.e("download url : ", downloadLink);
}
});
pd.dismiss();
}
});
}else {
Toast.makeText(getApplicationContext(),"No Image Selected", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Bitmap bitmap = null;
if (requestCode == IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null){
imageUri = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),imageUri);
_profilePicture1.setImageBitmap(bitmap);
_profilePicture1.setDrawingCacheEnabled(true);
_profilePicture1.buildDrawingCache();
} catch (IOException e) {
e.printStackTrace();
}
if (uploadTask != null && uploadTask.isInProgress()){
Toast.makeText(mContext,"Upload in Progress!", Toast.LENGTH_SHORT).show();
}
else {
try{
uploadImage();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
taskSnapshot.**getDownloadUrl**().toString(); //deprecated and removed
use below code for downloading Url
final StorageReference profileImageRef= FirebaseStorage.getInstance().getReference("profilepics/" + "abc_10123" + ".jpg");
profileImageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>()
{
#Override
public void onSuccess(Uri downloadUrl)
{
//do something with downloadurl
}
});
for latest version try
profileImageUrl = taskSnapshot.getStorage().getDownloadUrl().toString();
Try using this:
taskSnapshot.getMetadata().getReference().getDownloadUrl().toString()
FirebaseStorage Library version 19.0.1 works with
String download_image_path = task.getResult().getUploadSessionUri().toString();
//firebase database
implementation 'com.google.firebase:firebase-database:15.0.0'
//firebase storage
implementation 'com.google.firebase:firebase-storage:15.0.0'
.getDownloadUrl() method is removed from later versions , i have changed it to 15.0.0 and works perfectly fine.You can find these in build.gradle(module:app)
Only that...
taskSnapshot.getStorage().getDownloadUrl();
Task<Uri> result = taskSnapshot.getStorage().getDownloadUrl();
result.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String photoStringLink = uri.toString();
mDatavaseRef.push().setValue(photoStringLink);
}
});
This will work:
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Task<Uri> result = taskSnapshot.getMetadata().getReference().getDownloadUrl();
result.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String photoStringLink = uri.toString();
Log.i("urlimage", photoStringLink);
}
});
}
});
Try this:
Uri download_uri ;
final Map<String, String> userData = new HashMap<>();
if (task != null) {
//download_uri = task.getResult().getDownloadUrl();
download_uri = task.getResult().getUploadSessionUri();
}
else {
download_uri= imageUri;
}
userData.put("Image", download_uri.toString());
userData.put("name",username);
userData.put("category",category);
userData.put("status",status);
this is help help me with the last dependencies in 04/2020
// Get a reference to store file at chat_photos/<FILENAME>
final StorageReference photoRef = mChatPhotosStorageReference.child(selectedImageUri.getLastPathSegment());
photoRef.putFile(selectedImageUri).addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//When the image has successfully uploaded, get its downloadURL
photoRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Uri dlUri = uri;
FriendlyMessage friendlyMessage = new
FriendlyMessage(null, mUsername, dlUri.toString());
Use Firebase storage version 15.0.0.
Uri downloadUrl=taskSnapshot.getDownloadUrl().toString();
you can also use Picasso dependencies . its easy to use for uploading image in firebase.
ActivityFile:
Picasso.get().load(uriImage).into(ImageUri);
app-gradle:
com.squareup.picasso:picasso:2.71828
This will Solve Your Problem....
if(uploadTask.isSuccessfull()){
Task<Uri> uriTask=uploadTask.getResult().getStorage().getDownloadUrl(); while(!uriTask.isSuccessful());
Uri downloadUri=uriTask.getResult();
final String download_url=downloadUri.toString();
}
private void uploadImageTask() {
Uri uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/Pictures/OnShot.jpg"));
StorageReference storageReference = this.storageReference.child("images/" + UUID.randomUUID().toString());
storageReference.putFile(uri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
taskSnapshot.getStorage().getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
Log.d(TAG, "Download URL: " + String.valueOf(task.getResult()));
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
// ...
}
});
}
I still having this error. What might be wrong? I already changed the permissions, and users to anonymous.
For Java Code
String downloadUrl = taskSnapshot.getMetadata().getReference().getDownloadUrl().toString();
For Kotlin
val downloadUrl = taskSnapshot.getMetadata()?.getReference()?.getDownloadUrl()?.toString()
there is nothing wrong with the depencies. You just have to downgrade your firebase depencies. This is because it hasnt been updated yet..
Once you have uploaded a file to Firebase how can you get it's URL so that you can store that for later use? I want to write the URL to a Firebase Database so that other users can access the image.
I am uploading the file like so:
public void uploadFile()
{
StorageReference filepath = mstorageRef.child("folder").child(filename);
Uri File= Uri.fromFile(new File(mFileName));
filepath.putFile(File).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
{
Toast.makeText(MtActivity.this, "Upload Done", Toast.LENGTH_LONG).show();
}
});
}
I have confirmed that the files are in fact uploading so now I just need the URL which I can write to my Database. However when I tried to do this:
Uri downloadUrl = taskSnapshot.getMetadata().getDownloadUrl();
It gives me an error and says This method should only be accessed from tests or within private scope
I'm not sure what that means and I also don't know why I would be getting that error since I'm following this example provided by Firebase.
Is there a new way of getting the URL?
Also, is that URL unique to that item in particular? Meaning if I store it to a database and try to access it later will I be able to do so?
You're using UploadTask.getDownloadUrl() which is deprecated. You can use StorageReference.getDownloadUrl().
In your case you can try this as -
filepath.putFile(File).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
{
filepath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Uri downloadUrl = uri;
//Do what you want with the url
}
Toast.makeText(MtActivity.this, "Upload Done", Toast.LENGTH_LONG).show();
}
});
Take care that StorageReference.getDownloadUrl() returns Task, which must be handled asynchronously, you cannot do Uri downloadUrl = photoRef.getDownloadUrl().getResult(); else you will get java.lang.IllegalStateException: Task is not yet complete
As already mentioned above, StorageReference.getDownloadUrl()
returns Task.
Here is my code:
filepath.putFile(imageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if(task.isSuccessful()){
filepath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Uri downloadUri = uri;
String download_url = uri.toString();
mUserDatabase.child("image").setValue(download_url).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()) {
mProgressDialog.dismiss();
Toast.makeText(SettingActivity.this, "Successfully uploaded", Toast.LENGTH_LONG).show();
}else {
Toast.makeText(SettingActivity.this, "Error happened during the upload process", Toast.LENGTH_LONG).show();
}
}
});
}
});
}else{
Toast.makeText(SettingActivity.this, "Error happened during the upload process", Toast.LENGTH_LONG ).show();
}
}
});
This method works too and is a little bit simpler.
It's not something "incredible", but it reduces your code to a few lines. Hope that it's a helpful answer.
StorageReference filepath = mstorageRef.child("folder").child(filename);
filepath.putFile(File).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot){
Uri downloadUrl = filepath.getDownloadUrl(); // here is Url for photo
Toast.makeText(MtActivity.this, "Upload Done", Toast.LENGTH_LONG).show();
}
});
Here is hot I did it
1) This is my Upload and get http url code:
UploadTask uploadTask = FirebaseStorage.getInstance().getReference().child("id").child("filename")
.putFile(uri);
Task<Uri> urlTask = uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
}
// Continue with the task to get the download URL
return FirebaseStorage.getInstance().getReference().child(user.getUid()).child(avatarName).getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
FirebaseDatabase.getInstance().getReference().child(user.getUid())
.child(avatarName)
.child("avatar_image")
.setValue(downloadUri.toString());
Toast.makeText(getContext(), "Success", Toast.LENGTH_SHORT).show();
} else {
// Handle failures
// ...
Toast.makeText(getContext(), "Failed", Toast.LENGTH_SHORT).show();
}
}
});
2) This my onActivityResult code after pickup image from gallery
#Override
public 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 = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContext().getContentResolver(), uri);
// Log.d(TAG, String.valueOf(bitmap));
ivAvatarPic.setImageBitmap(bitmap);
//ImageView imageView = (ImageView) findViewById(R.id.imageView);
//imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Use following code
val imageGalleryRef = storageReference?.child(name + "_gallery")
val uploadTask = imageGalleryRef.putFile(file)
uploadTask.addOnFailureListener({ e ->
Log.e(TAG, "onFailure sendFileFirebase " + e.message)
}).addOnCompleteListener(
object : OnCompleteListener<UploadTask.TaskSnapshot> {
override fun onComplete(p0: Task<UploadTask.TaskSnapshot>) {
imageGalleryRef.downloadUrl.addOnSuccessListener { e ->
run {
downloadUrl = e.toString() // e is image download Uri
}
}
}
}
)
Try this one:
filepath.putFile(File).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if(task.isSuccessful()){
String fileUri = task.getResult().getUploadSessionUri().toString();
// Do whatever you want with fileUri
}
}
}) ;
filePath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String category = spinner.getSelectedItem().toString();
String title = ((EditText) findViewById(R.id.post_title)).getText().toString();
String description = ((EditText) findViewById(R.id.post_description)).getText().toString();
final Post post = new Post(userId, category, title, description, latitude, longitude, true);
post.setAddressList(addressLine);
post.setContact(contact);
if (addressLine != null) {
post.setPlace(addressLine.split(",")[2]);
}
post.setId(key);
post.setImage(uri.toString());
databaseReference.setValue(post).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
((EditText) findViewById(R.id.post_title)).setText("");
((EditText) findViewById(R.id.post_description)).setText("");
postImageButton.setImageURI(null);
progressBarDialog.dismiss();
Toast.makeText(PostActivity.this, "Your request is sucessfully completed", Toast.LENGTH_SHORT).show();
} else if (!task.isSuccessful()) {
progressBarDialog.dismiss();
Toast.makeText(PostActivity.this, "Your request is not completed", Toast.LENGTH_SHORT).show();
}
}
});
}
});
}
change the URI to URL
val urlTask = uploadTask.continueWith { task ->
if (!task.isSuccessful) {
task.exception?.let {
throw it
}
}
spcaeRef.downloadUrl
}.addOnCompleteListener { task ->
if (task.isSuccessful) {
val downloadUri = task.result
//URL
val url = downloadUri!!.result
} else {
//handle failure here
}
}
In Ionic 5 + capacitor, this is how I ended up being able to both monitor upload and get the finished file name.
The code was collected from google's own documentation + some google search (https://ionicthemes.com/tutorials/about/ionic-firebase-image-upload among others).
It is using canvas (as far as I understand) to generate a base64 string from an image. That worked, where ionic's File and Base64 didn't.
On the page, I have an <ion-progressbar> showing the percentage (this.downloadProgress) if it is > 0. I also have an <ion-img> with src=this.imageUrl that shows the picture when it's uploaded.
I couldn't get any of the techniques in above answers to work, wouldn't even compile. But I don't know enough to know why anyway.
Another caveat was that some of the example code used function() instead of arrow syntax
encodeImageUri(imageURI, function(image64) {
which needs rewriting to arrow syntax to bind/pass in "this" to the function called, like here:
encodeImageUri(imageURI, image64 => {
uploadImage(imageURI) {
console.log(`try upload ${imageURI}`)
let storageRef = firebase.storage().ref();
let imageRef = storageRef.child('image').child('imageName');
this.encodeImageUri(imageURI, image64 => {
// create upload task
const uplTask = imageRef.putString(image64, 'data_url');
uplTask.on('state_changed',
snapshot => {
var progress = (snapshot.bytesTransferred / snapshot.totalBytes);
console.log('Upload is ' + progress * 100 + '% done'); // might display this somewhere
this.downloadProgress = progress; // update progress bar
},
error => {
console.log('upload error');
},
() => {
uplTask.snapshot.ref.getDownloadURL()
.then(downloadURL => {
console.log('File available at', downloadURL);
this.imageUrl = downloadURL;
this.downloadProgress = -1; // negative values hide the progress bar
});
}
);
});
}
encodeImageUri(imageUri, callback) {
var c = document.createElement('canvas');
var ctx = c.getContext("2d");
var img = new Image();
img.onload = function () {
var aux:any = this;
c.width = aux.width;
c.height = aux.height;
ctx.drawImage(img, 0, 0);
var dataURL = c.toDataURL("image/jpeg");
callback(dataURL);
};
img.src = imageUri;
};
Of course this is kind of boring since it's always overwriting the same Firebase Storage file :) But that's fixable.
Not sure if this is what you're looking for as I am using Kotlin. This is what worked for me in my current project. I hope it will help someone else in the future.
Firstly I'm getting the image from the camera or from the gallery.
I'm using a current timestamp to make file names unique.
fun uploadFileFromMemory() {
showLoading()
val currentTimestamp = System.currentTimeMillis()
val storage = Firebase.storage("Your storage url")
// Create a storage reference from our app
val storageRef = storage.reference
// Create a reference to "mountains.jpg"
val mountainsRef = storageRef.child("images/picture$currentTimestamp.jpg")
// Get the data from an adminImageView as bytes
adminImageView.isDrawingCacheEnabled = true
adminImageView.buildDrawingCache()
val bitmap = (adminImageView.drawable as BitmapDrawable).bitmap
val baos = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val data = baos.toByteArray()
var uploadTask = mountainsRef.putBytes(data)
val urlTask = uploadTask.continueWithTask { task ->
if (!task.isSuccessful) {
task.exception?.let {
throw it
}
}
mountainsRef.downloadUrl
}.addOnCompleteListener { task ->
if (task.isSuccessful) {
val downloadUri = task.result
updateServicePicture(downloadUri.toString())
} else {
hideLoading()
showToast("Something went wrong")
}
}
After that, I am getting the URL of the newly updated file to update the picture URL property in my firestore database using this function.
fun updateServicePicture(url: String) {
val db = FirebaseFirestore.getInstance()
val id = arguments?.getString("id")
if (id !== null) {
val ref = db.collection("services").document(id)
// Set the "isCapital" field of the city 'DC'
ref
.update("picture", url)
.addOnSuccessListener { Log.d(TAG, "DocumentSnapshot successfully updated!")
hideLoading()
showToast("Picture has been successfully updated")
}
.addOnFailureListener { e -> Log.w(TAG, "Error updating document", e)
hideLoading()
showToast("Something went wrong")
}
}
}
hideLoading(), showloading() and showToast() are my functions for progressbar and toast.
I hope this helps someone out.
With the documentation and some testing, I eventually got it to work. Happy coding everyone.
Future<List<String>> uploadImages(List<String> filepaths) async {
List<String> uploadUrls = [];
await Future.wait(filepaths.map((String filepath) async {
FirebaseStorage storage = FirebaseStorage(storageBucket: 'gs://your-bucket-name.appspot.com');
StorageUploadTask uploadTask = storage.ref().child("images/${basename(filepath)}").putFile(File(filepath));
StorageTaskSnapshot storageTaskSnapshot;
StorageTaskSnapshot snapshot = await uploadTask.onComplete;
if (snapshot.error == null) {
storageTaskSnapshot = snapshot;
final String downloadUrl = await storageTaskSnapshot.ref.getDownloadURL();
uploadUrls.add(downloadUrl);
print('Upload success');
} else {
print('Error from image repo ${snapshot.error.toString()}');
throw ('This file is not an image');
}
}), eagerError: true, cleanUp: (_) {
print('eager cleaned up');
});
return uploadUrls;
}
}
Did you try taskSnapshot.getDownloadUrl()?
if that also doesn't work you can get the image location in success listener by mstorageRef.child("folder").child(filename).toString()
Try This :
final Uri uri = data.getData();
StorageReference filepath = mStorageRef.child("folder").child(filename);
filepath.putFile(uri).addOnSuccessListener(new
OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUri = taskSnapshot.getDownloadUrl();
//Getting url where image is stored
//downloadUri will store image URI
}
});