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

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));
}

Related

How to upload multiple images to firebase database using HashMap

I am working on a simple app that should work like uber, I want each driver to upload the image of his/her car while setting up his/her profile. I have successfully picked the two images and was able to save them to the firebaseStorage, I want to retrieve the link to the downloaded car Image and save it to the driver database reference along with his profile picture and other information but I am unable to do that. I create a method that returns a String so that I can use the String returned by that method as the link to the car Image but it's showing null in my database.
The method that should return the link to the downloaded car image:
private Uri profileImageUri, carImageUri;
private StorageReference storageProfilePicsRef, storageCarImageRef;
private StorageTask uploadProfileTask, uploadCarImageTask;
private String myProfileImaeUri = "", myCarImageUri = "";
private String uploadCarImage() {
if (carImageUri != null) {
final StorageReference storageReference = storageCarImageRef.child(mAuth.getCurrentUser().getUid() + ".jpg");
uploadCarImageTask = storageReference.putFile(carImageUri);
uploadCarImageTask.continueWithTask(new Continuation() {
#Override
public Object then(#NonNull Task task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
}
return storageReference.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadCarUri = task.getResult();
myCarImageUri = downloadCarUri.toString();
}
}
});
} else {
Toast.makeText(SettingsActivity.this, "Car Image Not Selected", Toast.LENGTH_SHORT).show();
}
return myCarImageUri;
}
This is the method that upload both the profile image and other information of the driver:
private void uploadProfilePicture() {
String carImageUriFromTheMethod = uploadCarImage();//I was trying to assigned the method that returns the carImage link as a String to this String type variable so that I can use it
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Updating Profile");
progressDialog.setMessage("Please wait while we are updating your account information");
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.show();
if (profileImageUri != null) {
final StorageReference fileRef = storageProfilePicsRef.child(mAuth.getCurrentUser().getUid() + ".jpg");
uploadProfileTask = fileRef.putFile(profileImageUri);
uploadProfileTask.continueWithTask(new Continuation() {
#Override
public Object then(#NonNull Task task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
}
return fileRef.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
myProfileImaeUri = downloadUri.toString();
int selectedID = radioGroup.getCheckedRadioButtonId();
male = (RadioButton)findViewById(selectedID);
female = (RadioButton) findViewById(selectedID);
if (male.isChecked()){
selectedGender = male.getText().toString();
}else if (female.isChecked()){
selectedGender = female.getText().toString();
}else {
selectedGender = "Not specify";
}
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("ProfileImage", myProfileImaeUri);
hashMap.put("name", name.getText().toString());
hashMap.put("city", city.getText().toString());
hashMap.put("age", age.getText().toString());
hashMap.put("maritalStatus", maritalStatus.getText().toString());
hashMap.put("phoneNumber", phoneNumber.getText().toString());
hashMap.put("country", country.getText().toString());
hashMap.put("address", address.getText().toString());
hashMap.put("gender", selectedGender);
hashMap.put("carName",carName.getText().toString());
hashMap.put("carColour", carColor.getText().toString());
hashMap.put("carPlateNumber", carPlateNumber.getText().toString());
hashMap.put("carImage", carImageUriFromTheMethod);//I now call the string here
}
databaseReference.child(mAuth.getCurrentUser().getUid()).updateChildren(hashMap);
progressDialog.dismiss();
if (getType.equalsIgnoreCase("Driver")) {
startActivity(new Intent(SettingsActivity.this, DriversMapsActivity.class));
Toast.makeText(SettingsActivity.this, "Profile Information Updated Successfully", Toast.LENGTH_SHORT).show();
finish();
} else {
startActivity(new Intent(SettingsActivity.this, CustomerMapsActivity.class));
Toast.makeText(SettingsActivity.this, "Profile Information Updated Successfully", Toast.LENGTH_SHORT).show();
finish();
}
} else {
Toast.makeText(SettingsActivity.this, "Error Occured", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
}
});
} else {
Toast.makeText(SettingsActivity.this, "Profile Image Not Selected", Toast.LENGTH_SHORT).show();
}
}
Here is my database which shows that the carImage is null, but there is a car Image in the firebaseStorage:
"Driver": {
"2oKrtyUa3FX1wyHAhplsxbVaPZU2": {
"ProfileImage": "https://firebasestorage.googleapis.com/v0/b/ride-booking-app-e8a95.appspot.com/o/Profile%20Images%2F2oKrtyUa3FX1wyHAhplsxbVaPZU2.jpg?alt=media&token=442b14b3-ffb8-4356-b0c0-4c77021fe391",
"address": "Ikot Obong",
"age": "28",
"carColour": "black",
"carImage": "",//this is where the link supposed to appear as it's seen in the profile image
"carName": "Range Rover sport",
"carPlateNumber": "aa377-ktm",
"city": "Ikot Abasi",
"country": "Nigeria",
"gender": "Male",
"maritalStatus": "single",
"name": "Captain Elijah",
"phoneNumber": "08168989070"
}
}
Thanks for help
All the operations you are doing (uploading the image, getting its download URL, and writing to the database) are asynchronous, which your code ignores.
If you log the myCarImageUri in uploadCarImage right before you return it, you'll see it's null, which is the case because your onComplete for the upload hasn't run yet (another log would show that too).
The correct way to handle the uploads is as you already do for the myProfileImaeUri in your uploadProfilePicture method: nesting the callbacks, so that they execute in the correct order. You'll need to do the same for the car image.
To learn more about this problem, I recommend checking out some of the top answers on the asynchronous behavior of getDownloadUrl(), such as my answers to:
Can someone help me with logic of the firebase on success listener
How do I get files synchronized from Firebase in Android?
Why can't this retieve the download URL of an image on Firebase Storage?
I'd also recommend reading Doug's excellent series of blog posts on becoming a Firebase task master.

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()));

Can not get download URL for uploaded image to firebase android [duplicate]

This question already has answers here:
How to use getdownloadurl in recent versions?
(5 answers)
How can i upload and retrieve an image to firebase storage in android in 2018 (taskSnapshot/getDownloadUrl deprecated) (Closed)
(3 answers)
Closed 2 years ago.
I have this code which uploads an image from imageview on the click of a button. Even if the image gets uploaded by this code, I'm unable to get the download url for the image which I can use in future reference purposes. Kindly help me in getting the download URL. FYI, the getDownloadURl() function has been deprecated and is not working. Thank you!
Button uploadBtn = findViewById(R.id.upload_btn);
uploadBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FirebaseStorage storage = FirebaseStorage.getInstance();
// Create a storage reference from our app
StorageReference storageRef = storage.getReferenceFromUrl("gs://'''''''.appspot.com/");
// Create a reference to "mountains.jpg"
StorageReference mountainsRef = storageRef.child(System.currentTimeMillis() + ".jpg");
// Create a reference to 'images/mountains.jpg'
StorageReference mountainImagesRef = storageRef.child("images" + System.currentTimeMillis() + ".jpg");
// While the file names are the same, the references point to different files
mountainsRef.getName().equals(mountainImagesRef.getName()); // true
mountainsRef.getPath().equals(mountainImagesRef.getPath()); // false
imageView.setDrawingCacheEnabled(true);
imageView.buildDrawingCache();
Bitmap bitmap = imageView.getDrawingCache();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = mountainsRef.putBytes(data);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
}
}).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.
String downloadUrl = taskSnapshot.getMetadata().getReference().getDownloadUrl().toString();
Toast.makeText(ClickImage.this, downloadUrl, Toast.LENGTH_SHORT).show();
}
});
}
});
I got this problem with me before, who gets to download Firebase correctly but not the link in downloadUrl.
After what I searched for the matter, there is a thing called AsyncTask and its method of work works to override the orders that need a greater period of time and executes the orders after it and when it is finished it returns to it
Solve this problem You can use this method to retrieve the value of downloadUrl
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
storageReference.getDownloadUrl().addOnCompleteListener(task -> {
String downloadUrl = Objects.requireNonNull(task.getResult()).toString();
});
I hope I simplified things for you and help you .

Retrieve user image from cloud firestorage into Imageview

I'm using java to develop an android application, I'm using cloud firestore and firebase storage to store the user's profile picture.
When a user logs in, he/she can upload a profile picture and it will be loaded into an imageView,
The images are successfully uploaded to the storage and successfully loaded into the imageView.
However, when I re-run the application and log into the account I uploaded the picture from, the picture can't be loaded into the imageView like before.
Here's my code for uploading the picture:
if (mImageUri != null){
file = mStorageRef.child(userId+".png");
UploadTask = file.putFile(mImageUri).addOnSuccessListener(newOnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(EditDonatorProfile.this,"Image uploaded successfully",Toast.LENGTH_SHORT).show();
String Link = mImageUri.toString();
Upload upload = new Upload(userId,Link);
db.collection("profilePicture").document(userId).set(upload);
}
});
}
else
{
Toast.makeText(this,"Choose a file first",Toast.LENGTH_SHORT).show();
}
and here's my retrieve code:
DocumentReference documentReference1 =db.collection("profilePicture").document(userId);
documentReference1.addSnapshotListener(this, new EventListener<DocumentSnapshot>() {
#Override
public void onEvent(#Nullable DocumentSnapshot documentSnapshot, #Nullable FirebaseFirestoreException e) {
String uri = documentSnapshot.getString("link");
StorageReference storageReference = StorageReference.getReference("Images/"+userId+".png");
if(uri == null)
return;
Uri link = Uri.parse(String.valueOf(uri));
Picasso.with(DonatorProfile.this).load(link).into(Photo);
}
});
getCurrentUser().updateProfile(new UserProfileChangeRequest.Builder()
.setPhotoUri().build());

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