1

I am able to retrieve the download imageUrl. The issue is when I am trying to store it in the Firebase Realtime Database, it is not getting saved or else it is going as null.

Even if I am trying to return the value it is returning null. My concern is how do I return the downloadUrl and store it into Realtime Database?

Code:

// store value into database
uploadImage();
QuestionModel model = new QuestionModel(question.getText().toString(),optionA.getText().toString(),optionB.getText().toString(),optionC.getText().toString(),
                        optionD.getText().toString(),correctAnswer.getText().toString(), explaination.getText().toString(),difficult , chapterName, indexNo, imageUrl);
setQuestiontoDatabase(modules, chapterName, subchapter1, model);
// UploadImage method
    private String uploadImage()
    {
        String imageUrl = null;
        if (filePath != null) {

            // Defining the child of storageReference
            StorageReference ref
                    = storageReference
                    .child(
                            "images/"
                                    + UUID.randomUUID().toString());

            // adding listeners on upload
            // or failure of image
            UploadTask 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();
                        String imageUrl = downloadUri.toString();
                        Log.i("Download url", imageUrl);
                        // update realtime database
                    } else {
                        Toast
                                .makeText(AddQuestion.this,
                                        "Failed ",
                                        Toast.LENGTH_SHORT)
                                .show();
                    }
                }
            });
        }
        return imageUrl;
    }

Question Model:

public class QuestionModel {

    public QuestionModel() {
    }

    private int index;
    private String question, optionA, optionB, optionC, optionD, correctAnswer,explaination, difficulty,ChapterName, imageUrl;

    public QuestionModel(String question, String optionA, String optionB, String optionC, String optionD, String correctAnswer, String explaination, String difficulty, String ChapterName, int index, String imageUrl) {
        this.question = question;
        this.optionA = optionA;
        this.optionB = optionB;
        this.optionC = optionC;
        this.optionD = optionD;
        this.correctAnswer = correctAnswer;
        this.explaination = explaination;
        this.difficulty = difficulty;
        this.ChapterName = ChapterName;
        this.index = index;
        this.imageUrl = imageUrl;
    }

    public String getQuestion() {
        return question;
    }

    public void setQuestion(String question) {
        this.question = question;
    }

    public String getOptionA() {
        return optionA;
    }

    public void setOptionA(String optionA) {
        this.optionA = optionA;
    }

    public String getOptionB() {
        return optionB;
    }

    public void setOptionB(String optionB) {
        this.optionB = optionB;
    }

    public String getOptionC() {
        return optionC;
    }

    public void setOptionC(String optionC) {
        this.optionC = optionC;
    }

    public String getOptionD() {
        return optionD;
    }

    public void setOtpionD(String otpionD) {
        this.optionD = otpionD;
    }

    public String getCorrectAnswer() {
        return correctAnswer;
    }

    public void setCorrectAnswer(String correctAnswer) {
        this.correctAnswer = correctAnswer;
    }

    public String getExplaination() {
        return explaination;
    }

    public void setExplaination(String explaination) {
        this.explaination = explaination;
    }

    public String getDifficulty() {
        return difficulty;
    }

    public void setDifficulty(String difficulty) {
        this.difficulty = difficulty;
    }

    public String getChapterName() {
        return ChapterName;
    }

    public void setChapterName(String chapterName) {
        this.ChapterName = chapterName;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public String getImageUrl() {
        return imageUrl;
    }
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Lav Sharma
  • 327
  • 1
  • 5
  • 23
  • just FWIW, the whole process for iOS https://stackoverflow.com/a/62626214/294884 – Fattie Aug 28 '21 at 19:07
  • Just since passing .. I would urge you to dump "realtime database" and just use ordinary normal modern "Firestore". – Fattie Aug 28 '21 at 19:10

1 Answers1

1

Both uploading data to Cloud Storage and getting the download URL, are asynchronous operations. While those operations are going on, your main code continues, and thus you end up writing to the database before the asynchronous operations are done.

You can most easily verify this in a debugger or with some well placed log statements: your setQuestiontoDatabase(...) runs before the Uri downloadUri = task.getResult(); ever is reached.

The solution for this is always the same: any code that needs the download URL must be inside the onComplete where that URL is available, or be called from there.

The simplest solution is to move your setQuestiontoDatabase(...) call into the onComplete callback:

    ...
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
    @Override
    public void onComplete(@NonNull Task<Uri> task) {
        if (task.isSuccessful()) {
            Uri downloadUri = task.getResult();
            String imageUrl = downloadUri.toString();
            Log.i("Download url", imageUrl);
            // update realtime database
            QuestionModel model = new QuestionModel(question.getText().toString(),optionA.getText().toString(),optionB.getText().toString(),optionC.getText().toString(),
                        optionD.getText().toString(),correctAnswer.getText().toString(), explaination.getText().toString(),difficult , chapterName, indexNo, imageUrl);
            setQuestiontoDatabase(modules, chapterName, subchapter1, model);
        } else {
            Toast.makeText(AddQuestion.this, "Failed ", Toast.LENGTH_SHORT).show();
        }
    }
});

Also see:

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