首页 > 解决方案 > Firebase 必须上传图像两次才能显示

问题描述

我正在构建一个聊天应用程序,我有一个加载消息的列表视图设置,并且我有一个图像选择器设置,可以将图像上传到 firebase 并在列表视图中显示它们。当我去上传图像时,我从图像选择器中选择图像,它被成功上传到 firestore 但没有显示,并且没有为它创建消息对象这是错误

2019-02-06 16:32:19.032 3810-5272/com.example.android.debateapp E/StorageException: {  "error": {    "code": 404,    "message": "Not Found.  Could not get object"  }}
java.io.IOException: {  "error": {    "code": 404,    "message": "Not Found.  Could not get object"  }}
    at com.google.firebase.storage.obfuscated.zzj.zza(com.google.firebase:firebase-storage@@16.0.2:455)
    at com.google.firebase.storage.obfuscated.zzj.zza(com.google.firebase:firebase-storage@@16.0.2:3435)
    at com.google.firebase.storage.obfuscated.zzc.zza(com.google.firebase:firebase-storage@@16.0.2:65)
    at com.google.firebase.storage.obfuscated.zzc.zza(com.google.firebase:firebase-storage@@16.0.2:57)
    at com.google.firebase.storage.zzc.run(com.google.firebase:firebase-storage@@16.0.2:68)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:761)

但是如果我在图像将成功上传并显示后立即上传相同的图像

我进行了设置,以便将图像上传到firebase 存储,然后作为图像 url数据库显示在消息对象下的实时数据库中

代码:

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == GALLERY_PICK && resultCode == RESULT_OK) {

        Uri selectedImageUri = data.getData();

        StorageReference photoRef = mChatPhotosStorageReference.child(selectedImageUri.getLastPathSegment());

        photoRef.putFile(selectedImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

            }
        });
        photoRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
            @Override
            public void onSuccess(Uri uri) {

                String downloadUrl = uri.toString();Log.d("tag", downloadUrl);
                FriendlyMessage friendlyMessage = new FriendlyMessage(null, mUsername, downloadUrl);
                mMessagedatabaseReference.push().setValue(friendlyMessage);
            }
        });

完整代码

标签: androidfirebasefirebase-storage

解决方案


您在getDownloadUrl()文件完成上传之前调用。

putFile()是异步的,这意味着它会立即返回,并且您的回调会在一段时间后调用,只要上传完成。您的代码假设上传要么立即完成,要么阻塞当前线程,直到上传完成。这是行不通的。

当您知道上传完成时,您应该做的是在回调中调用 getDownloadUrl() 。

    photoRef.putFile(selectedImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            photoRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                @Override
                public void onSuccess(Uri uri) {
                    String downloadUrl = uri.toString();
                    Log.d("tag", downloadUrl);
                    FriendlyMessage friendlyMessage = new FriendlyMessage(null, mUsername, downloadUrl);
            mMessagedatabaseReference.push().setValue(friendlyMessage);
                }
            });
        }
    });

推荐阅读