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

Posted

技术标签:

【中文标题】如何在实时数据库firebase android中存储下载图像url【英文标题】:How to store download image url in realtime database firebase android 【发布时间】:2021-10-28 04:45:22 【问题描述】:

我能够检索下载imageUrl。问题是当我尝试将它存储在 Firebase 实时数据库中时,它没有得到保存,否则它会以 null 的形式运行。

即使我试图返回值,它也会返回 null。我关心的是如何返回 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;
    

【问题讨论】:

只是FWIW,ios的全过程***.com/a/62626214/294884 刚刚通过.. 我会敦促你转储“实时数据库”,只使用普通普通的现代“Firestore”。 【参考方案1】:

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

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

解决方案总是相同:任何需要下载 URL 的代码必须该 URL 可用的onComplete 中,或者从在那里。

最简单的解决方案是将您的 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't get actual download Url of an image uploaded in firebase storage How to get URL from Firebase Storage getDownloadURL Can someone help me with logic of the firebase on success listener After Log.d(TAG, "downloadImgsUriArrayList:$downloadImagesUriList ") upload codes excute before for iterator's .addOnCompleteListener

【讨论】:

以上是关于如何在实时数据库firebase android中存储下载图像url的主要内容,如果未能解决你的问题,请参考以下文章

如何在Android Firebase实时数据库中按降序获取孩子[重复]

如何在不更改实时数据库中的 downloadUrl 的情况下更新 android 中 Firebase 存储中的位图图像

适用于 Android 的 Firebase 实时(在线)数据库的安全性如何?

关闭 Firebase 上的实时更改 (Android)

在 Firebase 实时数据库中保存数据 Android Studio Kotlin

如何让我的 android 应用程序连接到实时 firebase 数据库以在实时数据库中创建更新 toast?