1

First look at this. I call a function uploadUserPdf() inside submitProfile()

public void submitProfile() {
     if(!uploadUserPdf()) {
          return;
     }
     else {
        //...............
     }
}

And Here is the uploadUserPdf() function

private boolean uploadUserBiodataPdf() {
        Uri fileUri = Uri.parse(Pdf);
        final StorageReference storageReference = FirebaseStorage.getInstance().getReference().child("Pictures");
        StorageReference pdfRef = storageReference.child(mUser.getUid()).child(fileUri.getLastPathSegment());

        pdfRef.putFile(fileUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                pdfRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                    @Override
                    public void onSuccess(Uri uri) {
                        Pdf = uri.toString();
                        Toast.makeText(ContinueProfile.this, "Pdf Uploaded", Toast.LENGTH_LONG).show();
                    }
                });
            }
        });
        return false;
    }

I want to return true if file is successfully uploaded. But I cannot find any space to write return true. Is it possible to return the true value if file is successfully uploaded ??

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
thank you
  • 113
  • 8
  • have a look at [this](https://stackoverflow.com/questions/57330766/how-to-get-data-from-any-asynchronous-operation-in-android). you can use callbacks to invoke/return true or false – a_local_nobody Apr 26 '20 at 17:27

1 Answers1

1

Uploading the file to Firebase Storage happens asynchronously, since it may take time. While the uploading is going on in the background, your main code continues to execute in the foreground. Then when the upload completes, your onSuccess is called.

What this means is that by the time your return false runs, neither of your onSuccess methods have been called. And you can't return something now that hasn't happened yet.

For this reason any code that requites the download URL needs to be inside the onSuccess method that gets called when that download URL has been retrieved from the server. Like your Toast, which runs at the right time.

If you want to keep the code that uses the download URL separate from the code that generates it, you can pass in a custom callback interface, and then call that when you get the download URL:

public interface GetDownloadUrlCallback {
  void onCallback(String uri);
}
private boolean uploadUserBiodataPdf(GetDownloadUrlCallback callback) {
    Uri fileUri = Uri.parse(Pdf);
    final StorageReference storageReference = FirebaseStorage.getInstance().getReference().child("Pictures");
    StorageReference pdfRef = storageReference.child(mUser.getUid()).child(fileUri.getLastPathSegment());

    pdfRef.putFile(fileUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            pdfRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                @Override
                public void onSuccess(Uri uri) {
                    callback(uri.toString());
                }
            });
        }
    });

And then call it with:

GetDownloadUrlCallback(new GetDownloadUrlCallback() {
  @Override
  public void onCallback(String uri) {
    Log.i("GetDownloadUrlCallback", "Got uri: "+uri);
  }
});

Also see:

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807