I am getting this error when trying to retrieve image from firebase storage.
java.lang.IllegalStateException: Task is not yet complete on upload task.
Code:-
Uri imageUri = data.getData();
final StorageReference filePath = UserProfileImageRef.child(currentUserID + ".jpg");
filePath.putFile(imageUri)
.addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()) {
Toast.makeText(ProfileActivity.this, "Profile Image Uploaded", Toast.LENGTH_SHORT).show();
String downloadUri = filePath.getDownloadUrl().getResult().toString();
UserRef.child("profileImage").setValue(downloadUri).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Intent selfIntent = new Intent(ProfileActivity.this,ProfileActivity.class);
startActivity(selfIntent);
Toast.makeText(ProfileActivity.this, "Profile image uploaded to database", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
else {
String message = task.getException().getMessage();
Toast.makeText(ProfileActivity.this, "Error Occurred" + message, Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
}
});
}
}
});
filePath.getDownloadUrl() returns a Task that tracks the asynchronous work required to get the url. You can't just call getResult() on it immediately - you have to listen to its results like your are currently with putFile().
Read this for more information: How to get URL from Firebase Storage getDownloadURL
Related
I'm trying to get pictures from firebase storage and save it into the firestore.
I upload the picture once, and then I tried to open this app but it keeps stop.
java.lang.IllegalArgumentException: uri cannot be null
It shows this error.
Here is my code, and this is the part occurring error.
private void postButtonClicked(){
//immutable read-only variable
final String title = ((EditText)findViewById(R.id.titleEditText)).getText().toString();
final String contents = ((EditText)findViewById(R.id.contentsEditText)).getText().toString();
if(!title.trim().isEmpty() || !contents.trim().isEmpty()){
final StorageReference postRef = storageReference.child("post_images").child(FieldValue.serverTimestamp().toString()+".jpg");
postRef.putFile(postImageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if(task.isSuccessful()){
postRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
HashMap<String, Object> writeinfoMap = new HashMap<>();
writeinfoMap.put("image", uri.toString());
writeinfoMap.put("title", title);
writeinfoMap.put("contents", contents);
writeinfoMap.put("time", FieldValue.serverTimestamp());
// postMap.put("user", user);
firestore.collection("post").add(writeinfoMap).addOnCompleteListener(new OnCompleteListener<DocumentReference>() {
#Override
public void onComplete(#NonNull Task<DocumentReference> task) {
if(task.isSuccessful()){
startActivity(new Intent(WritePostActivity.this, MainActivity.class));
Toast.makeText(WritePostActivity.this, "posted!", Toast.LENGTH_SHORT).show();
finish();
}else{
String error = task.getException().getMessage();
Toast.makeText(WritePostActivity.this,"Error: "+error,Toast.LENGTH_SHORT).show();
}
}
});
}
});
}else{
String error = task.getException().getMessage();
Toast.makeText(WritePostActivity.this,"Error: "+error,Toast.LENGTH_SHORT).show();
}
}
});
}else{
Toast.makeText(this,"please enter the title.", Toast.LENGTH_SHORT).show();
}
}
please help me to find out the error and fix it. Thanks
I tried to resolve this with similar threads and answers here but completely failed.
My image is getting stored in firebase storage, and the database upload link is working but its always the wrong link. I get "com.google.android.gms.tasks.zzu#8045166" so the image is not displaying on the app
This is the overall code with the old version of GetDownloadUrl
private void InitializeFields()
{
UpdateAccountSettings = (Button) findViewById(R.id.update_settings_button);
userName = (EditText) findViewById(R.id.set_user_name);
userStatus = (EditText) findViewById(R.id.set_profile_status);
userProfileImage = (CircleImageView) findViewById(R.id.set_profile_image);
loadingBar = new ProgressDialog(this);
SettingsToolBar = (Toolbar) findViewById(R.id.settings_toolbar);
setSupportActionBar(SettingsToolBar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowCustomEnabled(true);
getSupportActionBar().setTitle("Account Settings");
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==GalleryPick && resultCode==RESULT_OK && data!=null)
{
Uri ImageUri = data.getData();
CropImage.activity()
.setGuidelines(CropImageView.Guidelines.ON)
.setAspectRatio(1, 1)
.start(this);
}
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE)
{
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if (resultCode == RESULT_OK)
{
loadingBar.setTitle("Set Profile Image");
loadingBar.setMessage("Please wait, your profile image is updating...");
loadingBar.setCanceledOnTouchOutside(false);
loadingBar.show();
Uri resultUri = result.getUri();
StorageReference filePath = UserProfileImagesRef.child(currentUserID + ".jpg");
filePath.putFile(resultUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task)
{
if (task.isSuccessful())
{
Toast.makeText(SettingsActivity.this, "Profile Image uploaded Successfully...", Toast.LENGTH_SHORT).show();
//--------------------------------------------->>
final String downloaedUrl = task.getResult().getDownloadUrl().toString(); **
//---------------------------------------------<<
RootRef.child("Users").child(currentUserID).child("image")
.setValue(downloaedUrl)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task)
{
if (task.isSuccessful())
{
Toast.makeText(SettingsActivity.this, "Image save in Database, Successfully...", Toast.LENGTH_SHORT).show();
loadingBar.dismiss();
}
else
{
String message = task.getException().toString();
Toast.makeText(SettingsActivity.this, "Error: " + message, Toast.LENGTH_SHORT).show();
loadingBar.dismiss();
}
}
});
}
else
{
String message = task.getException().toString();
Toast.makeText(SettingsActivity.this, "Error: " + message, Toast.LENGTH_SHORT).show();
loadingBar.dismiss();
}
}
});
}
}
}
i tried this
filePath.putFile(resultUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task)
{
if (task.isSuccessful())
{
//--- what i tried instead of: final String downloaedUrl = task.getResult().getDownloadUrl().toString();
final String downloadUrl = filePath.getDownloadUrl().toString();
Toast.makeText(SettingsActivity.this, "Profile Image uploaded Successfully...", Toast.LENGTH_SHORT).show();
The method getDownloadUrl() is executed asynchronously. So you can't call toString() directly after. You will need to attach a callback. Also, getDownloadUrl() in UploadTask.TaskSnapshot is deprecated. So you can do this instead:
filePath.putFile(resultUri).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 filePath.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
// retrieve your uri here
Uri downloadUri = task.getResult();
Log.d("TEST", "download uri: " + downloadUri.toString());
} else {
// load failed. Handle exception from task.getException()
}
}
});
I am using Firebase upload and I want to write the uploaded method in a class out of the activity as I want to use it several times and at the same time I want to use ProgressBar that shows the progress and as it is known we can't use findViewById out of activity or Fragment.
uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
taskSnapshot.getError();
float progress = (float) ((100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount());
System.out.println("Upload is " + progress + "% done");
**Here I wanna use a progressBar**
}
}).addOnPausedListener(new OnPausedListener<UploadTask.TaskSnapshot>() {
#Override
public void onPaused(UploadTask.TaskSnapshot taskSnapshot) {
System.out.println("Upload is paused");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
int errorCode = ((StorageException) exception).getErrorCode();
String errorMessage = exception.getMessage();
// test the errorCode and errorMessage, and handle accordingly
Log.d(TAG, "onSuccess: The photo has NOT been uploaded" + errorCode + errorMessage);
Toast.makeText(mContext, "Sorry the photo has not been uploaded .. Please Try again", Toast.LENGTH_SHORT);
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
circleProgressBar.setVisibility(View.GONE);
Log.d(TAG, "onSuccess: The photo is being uploaded");
Toast.makeText(mContext, "The photo has been uploaded successfully", Toast.LENGTH_SHORT).show();
//
}
}).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 ref.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
if (downloadUri != null){
String photoStringUrl = downloadUri.toString();
Log.d(TAG, "onComplete: Upload " + photoStringUrl);
//Inserting the profile photo into database {user_profile_account}
firebaseUtilities.saveProfilePhotoToDatabase(photoStringUrl);
}
}
You can pass Activity as a parameter instead of Context.
Basically I have created a class called 'Club'. I save a new club to firebase realtime database successfully with no real problems, until I want to add an imageURL (called clubImage) from Firebase Storage to my club class.
I am able to succesfully upload my image to Firebase Storage using the below code.
private void uploadImage() {
//upload selected image to database
//code from https://code.tutsplus.com/tutorials/image-upload-to-firebase-in-android-application--cms-29934
if(filePath != null)
{
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Uploading...");
progressDialog.show();
final StorageReference ref = storageReference.child("images/"+ UUID.randomUUID().toString());
ref.putFile(filePath)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
progressDialog.dismiss();
Toast.makeText(AddClubActivity.this, "Uploaded", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(AddClubActivity.this, "Failed "+e.getMessage(), Toast.LENGTH_SHORT).show();
}
})
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0*taskSnapshot.getBytesTransferred()/taskSnapshot
.getTotalByteCount());
progressDialog.setMessage("Uploaded "+(int)progress+"%");
}
});
}
}
This all works fine. However, in the same method, I also have this code, which is where I try to get my downloadURL for the uploaded image.
ref.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Uri downloadUrl = uri;
clubImage = downloadUrl.toString();
}
});
I know it is inefficient to have two OnSuccessListeners for the same thing, I am just not sure how else to go about both uploading an image and getting the downloadUrl at the same time.
Regardless, this doesn't work, and my new club saves without the clubImage field.
I get the error: E/StorageException: StorageException has occurred.
Object does not exist at location.
Does anyone know how to fix this?
Thanks.
I know it is inefficient to have two OnSuccessListeners for the same thing
You have two tasks that you're trying to complete:
Upload a file
Get the download URL for that file
Since these are two separate tasks, you'll need two OnSuccessListeners. There is nothing inefficient about this, nor are the tasks the same.
The Firebase documentation on getting a download URL after uploading shows precisely how to complete these two tasks in succession:
final StorageReference ref = storageRef.child("images/mountains.jpg");
uploadTask = ref.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 ref.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
} else {
// Handle failures
// ...
}
}
});
You'll note that this code first completes the uploadTask (which uploads the file) and only then starts a new task to get the download URL. Executing the tasks in this sequence prevents the "Object does not exist at location" error message you get.
try using this:
private Uri ImageUri; //and get image from gallery intent to this ImageUri
...............
StorageReference filePath = FirebaseStorage.getInstance().getReference().child("Club Images").child(ImageUri.getLastPathSegment() + ".jpg");
filePath.putFile(ImageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task)
{
if(task.isSuccessful())
{
downloadUrl = task.getResult().getDownloadUrl().toString();
updatetoFirebaseDatabase();
}
else
{
String message = task.getException().getMessage();
}
}
});
...........
create updatetoFirebaseDatabase(String imageUrl) method:
updatetoFirebaseDatabase(String imageUrl){
//implement FirebaseDatabase setvalue method with given image URL
}
I am trying to retrieve all users posts from firebase database and want to display it on Main Activity with the help Recycler View and Firebase Recycler Adapter.
But After Successfully Uploading The Image to Firebase database , i can see the uploaded image in storage section of firebase console but in database section it's showing something like -
com.google.android.gms.tasks.zzu#3c50f45
So I think the problem is with this line of code :
downloadUrl = task.getResult().getStorage().getDownloadUrl().toString();
CODE:
private Uri ImageUri;
private StorageReference PostsImagesRefrence;
private DatabaseReference UsersRef, PostsRef;
PostsImagesRefrence = FirebaseStorage.getInstance().getReference();
PostsRef = FirebaseDatabase.getInstance().getReference().child("Posts");
StorageReference filePath = PostsImagesRefrence.child("Post Images").child(ImageUri.getLastPathSegment() + postRandomName + ".jpg");
filePath.putFile(ImageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>()
{
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task)
{
if(task.isSuccessful())
{
downloadUrl = task.getResult().getStorage().getDownloadUrl().toString();
Toast.makeText(PostActivity.this, "image uploaded successfully to Storage...", Toast.LENGTH_SHORT).show();
SavingPostInformationToDatabase();
}
else
{
String message = task.getException().getMessage();
Toast.makeText(PostActivity.this, "Error occured: " + message, Toast.LENGTH_SHORT).show();
}
}
});
Design View And Actual Output Image:
Design View
View After Running
Please Try To provide me a correct code , help me as i am a newbie and don't know about Android Studio , and want to complete this College Project.
Try changing
String userFullName = dataSnapshot.child("fullname").getValue().toString();
String userProfileImage = dataSnapshot.child("profileimage").getValue().toString();
To
String userFullName = dataSnapshot.child("fullname").getValue(String.class);
String userProfileImage = dataSnapshot.child("profileimage").getValue(String.class);
EDIT: Try this
dateRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri downloadUrl)
{
downloadUrlString = downloadUrl.toString();
}
});
Solved It , I was using old method for storing the image to firebase database.
Following changes has been done to solve it :
final StorageReference filePath = PostsImagesRefrence.child("Post Images").child(ImageUri.getLastPathSegment() + postRandomName + ".jpg");
final UploadTask uploadTask =filePath.putFile(ImageUri);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e)
{
String message =e.toString();
Toast.makeText(PostActivity.this, "Error occured: " + message, Toast.LENGTH_SHORT).show();
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>()
{
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
{
Toast.makeText(PostActivity.this, "Image uploaded successfully to Storage...", Toast.LENGTH_SHORT).show();
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();
}
downloadUrl= filePath.getDownloadUrl().toString();
return filePath.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>()
{
#Override
public void onComplete(#NonNull Task<Uri> task)
{
if (task.isSuccessful())
{
downloadUrl = task.getResult().toString();
Toast.makeText(PostActivity.this, "Stored Image Successfully to Database", Toast.LENGTH_SHORT).show();
SavingPostInformationToDatabase();
}
}
});
}