如何在实时数据库 firebase android 中存储下载图像 url

How to store download image url in realtime database firebase android

我可以检索下载 imageUrl。问题是当我试图将它存储在 Firebase 实时数据库中时,它没有被保存,否则它会变成 null.

即使我试图 return 值也是 returning null。我关心的是如何 return downloadUrl 并将其存储到实时数据库中?

代码:

// 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;
    }

问题模型:

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;
    }
}

将数据上传到 Cloud Storage 和获取下载 URL 都是异步操作。当这些操作正在进行时,您的主要代码仍在继续,因此您最终会在异步操作完成之前写入数据库。

您可以在调试器中或使用一些妥善放置的日志语句最轻松地验证这一点:您的 setQuestiontoDatabase(...) 在 之前 运行 Uri downloadUri = task.getResult(); 曾经达到。

这个问题的解决方案始终相同:任何需要下载URL的代码必须 onComplete URL 可用的地方,或者从那里调用。

最简单的解决方案是将您的 setQuestiontoDatabase(...) 调用移至 onComplete 回调中:

    ...
}).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();
        }
    }
});

另见:

  • Can someone help me with logic of the firebase on success listener