Firebase upload listeners never get fired - java

I am building an android application that uploads photos from a device to a Firebase storage. The images are properly uploaded but I can't get the upload listeners to work. I have gone through the documentation here and implemented the exact same solution:
System.out.println("Starting upload");
Uri file = Uri.fromFile(new File("myPath"));
StorageReference Ref = storageRef.child("images/"+file.getLastPathSegment());
uploadTask = Ref.putFile(file);
// Register observers to listen for when the download is done or if it fails
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// NEVER EXECUTES
System.out.println("upload failed");
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// NEVER EXECUTES
System.out.println("upload succeeded");
}
});
I can see the first line printed "Starting upload". But that's it. The same goes for OnCompleteListener if I add it but it's omitted here.
What is going wrong?

Try OnCompleteListener
uploadTask = Ref.putFile(file);
uploadTask.addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
System.out.println("upload succeeded");
} else {
System.out.println("upload failed");
}
}
});

Related

Firebase E/StorageException: StorageException has occurred. Object does not exist at location

I am trying to upload 4 different images to firebase storage, my code works with a single image, but whenever I try to upload multiple images I get
E/StorageException: StorageException has occurred.
Object does not exist at location.
Code: -13010 HttpResult: 404
2021-11-18 22:45:16.584 com.example.test E/StorageException: { "error": { "code": 404, "message": "Not Found." }}
java.io.IOException: { "error": { "code": 404, "message": "Not Found." }}
at com.google.firebase.storage.network.NetworkRequest.parseResponse(NetworkRequest.java:445)
at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(NetworkRequest.java:462)
at com.google.firebase.storage.network.NetworkRequest.processResponseStream(NetworkRequest.java:453)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:272)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:289)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:76)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:68)
at com.google.firebase.storage.GetDownloadUrlTask.run(GetDownloadUrlTask.java:77)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
This is my code to upload images to firebase storage and even after getting errors, I can see the images on firebase Storage but I am getting the error on the app.
private synchronized void UploadToFireBaseStorage(ArrayList<String> filePath,int type) {
final ArrayList<String> multipleImages = new ArrayList<>();
Log.d(TAG,"Size of File at Upload Method "+filePath.size());
if (filePath.size()==0){
return;
}
Uri fileUri = null;
for (String s : filePath) {
if (s.contains(".jpg")) {
fileUri = Uri.fromFile(new File(s));
} else {
fileUri = Uri.parse(s);
}
StorageReference mStorageReference = FirebaseStorage.getInstance().getReference();
Log.d(TAG, "UploadToFireBaseStorage: StorageRef "+mStorageReference);
storageReference = mStorageReference.child("Photos").child(fileUri.getLastPathSegment());
Log.d(TAG, "UploadToFireBaseStorage: Storage Reference "+storageReference);
Log.d(TAG, "UploadToFireBaseStorage: File URI = "+fileUri);
String finalAttachmentType = attachmentType;
String finalUploadFolder = uploadFolder;
storageReference.putFile(fileUri).addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
storageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(#NonNull Uri uri) {
Log.d(TAG, "Image Uploaded ");
Log.d(TAG, "onSuccess: URI Uploaded == "+uri);
}
});
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = 100.0 * taskSnapshot.getBytesTransferred() / (double) taskSnapshot.getTotalByteCount();
Log.d(TAG, "Upload is " + progress + "% done");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "onFailure: "+s);
}
});
}
Log.d(TAG,"Image List "+multipleImages.toString());
}
These are the storage reference i got for 4 different images
Storage Reference gs://example-89902.appspot.com/Photos/Image%20IMG_1637256617899.jpg
Storage Reference gs://example-89902.appspot.com/Photos/Image%20IMG_1637256617949.jpg
Storage Reference gs://example-89902.appspot.com/Photos/Image%20IMG_1637256618132.jpg
Storage Reference gs://example-89902.appspot.com/Photos/Image%20IMG_1637256618070.jpg
Firebase Storage Rules:
Firebase Storage Rules
service firebase.storage {
match /b/bucket/o {
match /{allPaths=**} {
allow read, write;
}
}
}
According to the stack trace the problem seems to be related to obtaining the download url:
at com.google.firebase.storage.GetDownloadUrlTask.run(GetDownloadUrlTask.java:77)
It's probably caused by this code fragment:
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
storageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(#NonNull Uri uri) {
Log.d(TAG, "Image Uploaded ");
Log.d(TAG, "onSuccess: URI Uploaded == "+uri);
}
});
}
My guess is that there is some kind of race condition between the upload success callback and the instant in which the storage reference and the corresponding download url are available.
As suggested in the Firebase documentation, please, try modifying your code like this in order to obtain the download url:
private synchronized void UploadToFireBaseStorage(ArrayList<String> filePath,int type) {
final ArrayList<String> multipleImages = new ArrayList<>();
Log.d(TAG,"Size of File at Upload Method "+filePath.size());
if (filePath.size()==0){
return;
}
Uri fileUri = null;
for (String s : filePath) {
if (s.contains(".jpg")) {
fileUri = Uri.fromFile(new File(s));
} else {
fileUri = Uri.parse(s);
}
StorageReference mStorageReference = FirebaseStorage.getInstance().getReference();
Log.d(TAG, "UploadToFireBaseStorage: StorageRef "+mStorageReference);
storageReference = mStorageReference.child("Photos").child(fileUri.getLastPathSegment());
Log.d(TAG, "UploadToFireBaseStorage: Storage Reference "+storageReference);
Log.d(TAG, "UploadToFireBaseStorage: File URI = "+fileUri);
String finalAttachmentType = attachmentType;
String finalUploadFolder = uploadFolder;
UploadTask uploadTask = storageReference.putFile(fileUri).addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// The stuff you considerd appropriate
Log.d(TAG, "Image Uploaded ");
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = 100.0 * taskSnapshot.getBytesTransferred() / (double) taskSnapshot.getTotalByteCount();
Log.d(TAG, "Upload is " + progress + "% done");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "onFailure: "+s);
}
});
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();
Log.d(TAG, "onSuccess: URI Uploaded == "+downloadUri);
} else {
// Handle failures
// ...
}
}
});
}
Log.d(TAG,"Image List "+multipleImages.toString());
}
Previously UploadTask.TaskSnapshot had a getDownloadUrl() method, but it is no longer available. The subject has been discussed in different issues like this one, for instance, which provides further alternatives as well.
As a side note, and probably unrelated, but certainly curious, you pointed out in your comments that two of the images are uploaded successfully and two not. As you can see in the source code of Uploadtask, this kind of tasks are scheduled using the following code:
#Override
protected void schedule() {
StorageTaskScheduler.getInstance().scheduleUpload(getRunnable());
}
StorageTaskScheduler schedules uploads in a thread pool executor of a maximum of two threads:
private static final ThreadPoolExecutor UPLOAD_QUEUE_EXECUTOR =
new ThreadPoolExecutor(
2, 2, 5, TimeUnit.SECONDS, mUploadQueue, new StorageThreadFactory("Upload-"));
Maybe some uploads are being blocked by this thread pool as you are trying uploading a greater number of images that the available number of threads.
In contrast, the operation for obtaining the download url is performed in a different thread pool:
private static final ThreadPoolExecutor COMMAND_POOL_EXECUTOR =
new ThreadPoolExecutor(
5, 5, 5, TimeUnit.SECONDS, mCommandQueue, new StorageThreadFactory("Command-"));
As you can see, in this pool the number of threads is five and it means there is enough room to submit the get download task operations.
I reviewed the code and cannot find any leak, but it is certain that this difference may be related to your problem in any way.

E/StorageException: Unable to obtain an upload URL

I don't know why I'm getting this exception E/StorageException: Unable to obtain an upload URL whenever it gets to uploading file/image onto Firebase Storage. It's also returning W/NetworkRequest: error sending network request error. Although I don't experience any internet connectivity problems. I've also tried running this with another device but it results in the same thing.
firebaseAuth.createUserWithEmailAndPassword(inputEmail, inputPassword).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
firebaseAuth.getCurrentUser().sendEmailVerification().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull final Task<Void> task) {
final String uID = firebaseAuth.getCurrentUser().getUid();
if (task.isSuccessful()) {
storageReference = FirebaseStorage.getInstance().getReference("image").child(uID); // for image uploads
storageReference.putFile(image_uri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//image uri is taken care of in the onActivityResult method.
member.setImage_url(taskSnapshot.getUploadSessionUri().toString());
member.setEmail(email.getText().toString().trim());
member.setFname(fname.getText().toString().trim());
member.setLname(lname.getText().toString().trim());
df = FirebaseDatabase.getInstance().getReference("Member").child(uID); //points to the address
df.setValue(member).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
startActivity(new Intent(Register.this, Login.class));
Toast.makeText(Register.this, "Registered successfully, please verify your email.", Toast.LENGTH_LONG).show();
}
});
RprogressBar.setVisibility(View.INVISIBLE);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(Register.this, e.getMessage(), Toast.LENGTH_LONG).show();
RprogressBar.setVisibility(View.INVISIBLE);
}
});
} else {
Toast.makeText(Register.this, task.getException().getMessage(), Toast.LENGTH_LONG).show();
RprogressBar.setVisibility(View.INVISIBLE);
}
}
});
} else {
Toast.makeText(Register.this, task.getException().getMessage(), Toast.LENGTH_LONG).show();
RprogressBar.setVisibility(View.INVISIBLE);
}
I still only have the slightest idea of what is happening but I've seen some other answers from a similar post and they suggested using VPN I'm currently in the Philippines so if anyone is having a similar problem try using VPN.

Get the success or failure of a file upload on firebase in java outside the addOnSuccessListener (android app)

I am making an android app in java and I need to upload a file on firebase storage. The problem is that the methods onFailure and onSuccess are void and can't return anything ! I need to know when the upload is finished if it's a success or not...
I try too to modify a variable in the class or in the method but it dosn't works because the listener are asynchronous ...
Here is my java class :
public class MyFirebase {
// Upload picture to firebase
public Boolean uploadToFirebase (Uri path, String nameFile, FirebaseStorage storage) throws InterruptedException {
// Create a storage reference from the app
StorageReference storageRef = storage.getReference();
UploadTask uploadTask;
// START upload
Uri file = Uri.fromFile(new File(String.valueOf(path)));
final StorageReference ref = storageRef.child("scanned_images/"+nameFile);
uploadTask = ref.putFile(file);
// Register observers to listen for when the download is done or if it fails
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Log.d("upload", "uploadToFirebase: fail ");
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Log.d("upload", "uploadToFirebase: success ");
}
});
return uploadTask.isSuccessful();
}
}
You need to create listener for this because these calls happen asynchronously you can't return it like that.
You can create a interface like below.
public interface MyResponseListener {
void onSuccess();
void onFailure();
}
And pass it as a argument in your method.
// Upload picture to firebase
public void uploadToFirebase (Uri path, String nameFile, FirebaseStorage storage,
final MyResponseListener myResponseListener) throws InterruptedException {
// Create a storage reference from the app
StorageReference storageRef = storage.getReference();
UploadTask uploadTask;
// START upload
Uri file = Uri.fromFile(new File(String.valueOf(path)));
final StorageReference ref = storageRef.child("scanned_images/"+nameFile);
uploadTask = ref.putFile(file);
// Register observers to listen for when the download is done or if it fails
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Log.d("upload", "uploadToFirebase: fail ");
myResponseListener.onFailure();
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Log.d("upload", "uploadToFirebase: success ");
myResponseListener.onSuccess();
}
});
}
And finally use this where you like:
private void setListener() {
myFirebase.uploadToFirebase(path, nameFile, storage,new MyResponseListener() {
#Override
public void onSuccess() {
//handle success
}
#Override
public void onFailure() {
//hanlde failure
}
});
}
I think it's not possible, but maybe you can return the result of your function inside onSuccess and onFailure functions
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Log.d("upload", "uploadToFirebase: fail ");
return false
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Log.d("upload", "uploadToFirebase: success ");
return true
}
});

After upload a file in Android Firebase Storage how get the file download Url? getDownloadUrl() not working

In my new android firebase project, I used com.google.firebase:firebase-storage:16.0.1 library.
I get the following Error:
I opened another project that had library firebase-storage:15.0.2 and taskSnapshot.getDownloadUrl(); which worked on that project. but after using latest dependency library it's not working.
Now, how can I get the file URL?
Any way to get the file download link?
I had Found 2 solution for my issue.
Firebase Google Documentation :
//add file on Firebase and got Download Link
filePath.putFile(imageUri).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()){
Uri downUri = task.getResult();
Log.d(TAG, "onComplete: Url: "+ downUri.toString());
}
}
});
Another solution!
It's more easy and small than google Firebase documentation and I'll use it:
filePath.putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
filePath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Log.d(TAG, "onSuccess: uri= "+ uri.toString());
}
});
}
});
That method has been deprecated on version 16.0.1 (check Firebase release notes) so you have to use
StorageReference.getDownloadUrl()
If you want to get them after uploading the file, then you must check their documentation here. It is already updated.
taskSnapshot.getDownloadUrl() is deprecated so i recommend that in your addOnSuccessListener() method, you use your storageReference and call the getDownloadUrl() method in order to get the url of the file and you can do whatever you want with it. Hope it helps.
mUploadTask = storageRef.putFile(file).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// get the image Url of the file uploaded
storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
// getting image uri and converting into string
Uri downloadUrl = uri;
fileUrl = downloadUrl.toString();
}
});
}
});
that's how I'm getting download link in kotlin android.
ref.putFile(filePath!!)
.addOnSuccessListener {
val result = it.metadata!!.reference!!.downloadUrl;
result.addOnSuccessListener {
val imageLink = it.toString()
}
}
In this case is better to continue using addOnSuccessListener as you're using, but instead of using getDownloadUrl directly, you need to add a listener to that too.
Now the method is inside taskSnapshot.getMetadata().getReference() like this
filePath.putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
taskSnapshot.getMetadata().getReference().getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
// User uri here
}
});
}
});
Firebase upadated their method so kindly update yourself use this method kindly:
this is the basic line at which you feeling annoying, very simple justget the download path in this way
StorageReference ref = storageReference.child("images/"+ UUID.randomUUID().toString());
UploadTask 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();
}
// 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();
///here is your image url enjoy this
Toast.makeText(CloudStorageActivity.this, "Uploaded", Toast.LENGTH_SHORT).show();
}
} else {
// Handle failures
// ...
}
}
});

How to retrieve the download URL of an image from Firebase Storage?

I am watching an old tutorial about Firebase Storage. The getDownloadUrl() method from UploadTask.TaskSnapshot is no longer existent, and the documentation fails to be clear to me.
What I've implemented so far is the upload process and I can confirm it works, but getting the URL is a pain and I can't make the way they explain how to do it because:
1) Creating a Task<Uri> urlTask = uploadTask.add[...]() will result in the following error on the IDE:
I don't understand because it is specified in the docs.
2) Using reference.getDownloadUrl() will display a different URL compared to what is shown on the console when seeing the details of the uploaded image. The download URL the console shows is
https://firebasestorage.googleapis.com/v0/b/chatroom-e44e6.appspot.com/o/chat_photos%2F73185640?alt=media&token=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
while logging will show
com.google.android.gms.tasks.xxx#xxxxxxx
My full code at the moment:
if (requestCode == RC_PHOTO_PICKER) {
if (data != null) {
Toast.makeText(MainActivity.this, "Uploading...", Toast.LENGTH_SHORT).show();
Uri file = data.getData();
final StorageReference reference = mPhotoStorageReference.child(file.getLastPathSegment());
UploadTask upload = reference.putFile(file);
upload.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this, "Image could not be uploaded: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}).addOnCompleteListener(this, new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
ChatroomMessage message = new ChatroomMessage(null, mUsername, reference.getDownloadUrl().toString()); // <- com.google.android.gms.tasks.xxx#xxxxxxx
mMessagesDatabaseReference.push().setValue(message);
Toast.makeText(MainActivity.this, "Image uploaded!", Toast.LENGTH_SHORT).show();
}
});
}
}
My app already has Firebase UI implemented to handle login operations, and the rules are
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
I put the effort and wasted more time but here is the more generic and working solution
private void uploadImage() {
if (filePath != null) {
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Uploading...");
progressDialog.show();
final StorageReference ref = storageReference.child("images/" +currentFirebaseUser.getUid() + "");
ref.putFile(filePath)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
progressDialog.dismiss();
Task<Uri> urlTask = taskSnapshot.getStorage().getDownloadUrl();
while (!urlTask.isSuccessful());
Uri downloadUrl = urlTask.getResult();
Log.e("uri12",downloadUrl+"This is uri of image download");
Toast.makeText(AddItemActivity.this, "Uploaded", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(AddItemActivity.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 + "%");
}
});
}
}
You have Permission denied error it means you don't have permision for access data from firebase. Please check here
if your security rules is defined public then here is no need for permission and if it isn't public or secured then you need to login by auth before you getting data from firebase and if login success then you can continue your work.
check this it will help you to understanding firebase security rules.
After many attempts, I managed to solve it. This is the implementation:
Uri file = data.getData();
final StorageReference reference = mPhotoStorageReference.child(file.getLastPathSegment());
UploadTask upload = reference.putFile(file);
upload.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this, "Image could not be uploaded: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
upload.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 reference.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUrl = task.getResult();
ChatroomMessage message = new ChatroomMessage(null, mUsername, downloadUrl.toString());
mMessagesDatabaseReference.push().setValue(message);
Toast.makeText(MainActivity.this, "Image uploaded!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, task.getException().toString(), Toast.LENGTH_SHORT).show();
}
}
});

Categories