0

I am trying to create a method that will return the download URL of the uploaded image to Firebase Storage as a String, so that I can use that String and insert it into the Firebase real-time database using a HashMap when I call that method. This is what I have done, but it does not work. What could be the problem? Any help will be appreciated.

String getImageDownloadUrlFromUploadedImages(){
    final String[] myDownloadUrl = new String[1];
    if (resultUri !=null){
        final StorageReference fileReference;
        fileReference = storageReference.child(System.currentTimeMillis() + "." + getFileExtension(resultUri));
        uploadTask = fileReference.putFile(resultUri);
        uploadTask.continueWithTask(new Continuation(){
            @Override
            public Object then(@NonNull Task task) throws Exception {
                if (!task.isComplete()){
                    throw Objects.requireNonNull(task.getException());
                }
                return fileReference.getDownloadUrl();
            }
        }).addOnCompleteListener(new OnCompleteListener<Uri>() {
            @Override
            public void onComplete(@NonNull Task <Uri> task) {
                if (task.isSuccessful()){
                    Uri downloadUri = task.getResult();
                    myDownloadUrl[0] = downloadUri.toString();
                    loader.dismiss();
                    startActivity(new Intent(AskAQuestionActivity.this, MainActivity.class));
                    finish();
                }else {
                    String error = Objects.requireNonNull(task.getException()).toString();
                    Toast.makeText(AskAQuestionActivity.this, "Failed" + error, Toast.LENGTH_SHORT).show();
                }
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(AskAQuestionActivity.this, "Question could not be posted." , Toast.LENGTH_SHORT).show();
            }
        });
    }
    else {
        Toast.makeText(this, "No image is selected", Toast.LENGTH_SHORT).show();
    }
    return myDownloadUrl[0];
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
willy
  • 101
  • 1
  • 9
  • What do you mean by " but it does not work." ? What is the result? Did you try to debug your code ? – Gag Baghdasaryan Jul 01 '20 at 08:11
  • 1
    There is no way you can return `myDownloadUrl[0]` as a result of a method. Firebase API is asynchronous, so any code that needs data from the Firebase Storage, needs to be inside the `onComplete()` method, or be called from there. This **[answer](https://stackoverflow.com/questions/47847694/how-to-return-datasnapshot-value-as-a-result-of-a-method/47853774)** might help you with an idea ;) – Alex Mamo Jul 01 '20 at 08:11
  • @Gag Baghdasaryan The image is being uploaded, but I do not get the url when I saved the data to the real-time db using hashMap.put("image", getImageDownloadUrlFromUploadedImages()); – willy Jul 01 '20 at 08:19
  • Check the link can help you https://stackoverflow.com/a/61831549/8306570 – Adel B-Lahlouh Jul 01 '20 at 08:58
  • 1
    As @AlexMamo already mentioned, you return the ```myDownloadUrl[0]``` from you method, but you put the url in the array (```myDownloadUrl[0] = downloadUri.toString();```) inside OnComplete listener, so it will run later, after you code will reach the end of you method. – Gag Baghdasaryan Jul 01 '20 at 09:55
  • As others have commented, you cannot **return** the download URL, because by the time your `return myDownloadUrl[0]` runs, the `myDownloadUrl[0] = downloadUri.toString()` hasn't run yet. I recommend running the code in a debugger and setting some breakpoints to see that, as it'll make it much easier to reason about your code. See my linked question for the common solution, which is to use a custom callback. – Frank van Puffelen Jul 01 '20 at 14:11

0 Answers0