当前位置: 首页 > 知识库问答 >
问题:

上传至Firebase存储等待上传完成,然后上传至Firebase并返回任务

姬选
2023-03-14

我正在尝试将自定义对象上载到Firebase Firestore,但Firestore对象应包含下载图像url。我必须这样做的想法是先上传图像,等待图像完成,获取下载url的引用,更新我的自定义类,然后将其上传到Firestore。然后,当最后一次上传(上传到Firestore)完成时,我想通知我的视图。我想通过返回一个任务来实现这一点。以下是我上传图片的方法:

ref.putFile(file).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            ref.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                @Override
                public void onSuccess(Uri uri) {
                    //use uri to update object and then upload to firestore

                       mObject.setImageUri(uri)
                       uploadToFirestore(myObject);
                    }
                    Log.d(TAG, "onSuccess: uri= "+ uri.toString());
                }
            });
        }
    });`

我不确定如何返回Firstore上传的最终任务,因为它是在图像上传任务中完成的。我的目标是监听何时上传ToFireStore()完成,然后通知我的视图。如有任何建议,将不胜感激。谢谢!

编辑:我的结构类似于so-View从用户获取信息,并将其作为自定义对象传递给viewmodel。视图模型然后调用db来执行上传。我的想法是将一个任务从db返回到viewmodel,它将把所述任务返回到视图。查看检查是否完成,然后停止加载程序。这是思考这个问题的好方法吗?

共有2个答案

姜振濂
2023-03-14

我想出了如何解决这个问题。使用回调。像这样创建接口

public interface Callback {
  void result(Result result);
  void url(Uri downloadUrl);
}

注意:结果是一个有两个值的枚举类失败和成功,然后在视图中像这样调用视图模型

ViewModel.saveoBJECT(mObject, new Callback() {
        @Override
        public void result(Result result) {
            switch (result){
                case SUCCESS:
                    mProgressbar.setVisibility(View.GONE);
                    break;
                case FAILED:
                    Log.v(TAG, "Failed");
                    Toast.makeText(getApplicationContext(), "OOPS ERROR!", Toast.LENGTH_LONG).show();
                    break;
            }
        }

        @Override
        public void url(Uri downloadUrl) { }
    });

在你的数据库里做这样的事情

  uploadImage(Uri.parse(imageString), prepend, new Callback() {
            @Override
            public void result(Result result) {}

            @Override
            public void uri(Uri downloadUrl) {
                saveObjectInDB(downloadUrl, new Callback() {
                    @Override
                    public void result(Result result) {
                        callback.result(result);
                    }

                    @Override
                    public void url(Uri downloadUrl) { }
                });
            }
        });

在上传图像功能

 ref.putFile(file).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            ref.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                @Override
                public void onSuccess(Uri uri) {
                    callback.journey(uri);
                    Log.d(TAG, "onSuccess: uri= "+ uri.toString());
                }
            });
        }
    });

在SaveObjectInDB函数中,您可以这样做

 db.collection(DATABASE).add(O)
        .addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
            @Override
            public void onSuccess(DocumentReference documentReference) {
                Log.w(TAG, "Document upload complete");
                callback.result(Result.SUCCESS);
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.w(TAG, "Error adding uploading document", e);
                callback.result(Result.FAILED);
            }
        });
巫马嘉祯
2023-03-14

我的工作示例。

public class SomeClass {
    private String downloadUrl;
    private final FirebaseStorage storage = FirebaseStorage.getInstance();
    private int count = 0;

    public interface Callback {
        void callingBack();
        void getReady();
    }

    public int getCount() {
        return count;
    }

    private Callback callback;

    public void registerCallBack(Callback callback) {
        this.callback = callback;
    }


    public String getImageUri () {
        return downloadUrl;
    }

    public void uploadImage (String srcPath, String fileName, Context context, int size) {
        StorageReference storageRef = storage.getReference();
        StorageReference imageRef = storageRef.child(fileName);
        try {
            InputStream inputStream = new FileInputStream(new File(srcPath));
            imageRef.putStream(inputStream)
                    .continueWithTask(task -> imageRef.getDownloadUrl())
                    .addOnCompleteListener(task -> {
                        downloadUrl = task.getResult().toString();
                        callback.callingBack();
                        this.count++;
                        if (this.count == size) {
                            callback.getReady();
                            this.count = 0;
                        }
                    });
        } catch (Exception e) {
            Toast.makeText(context, "Connection error", Toast.LENGTH_LONG).show();
        }
    }    
}

活动代码

    public void someMehtod() {

            String fileName;
            String filePath;
            int size = YOUR_SIZE;
            String[] imgUrlList = new String[size];
            for (int i = 0; i < size; i++) {
                fileName = "img_" + i + ".jpg"; // set target file name
                filePath = "/storage/emulated/0/Download/images_" + i + ".jpg"; // for example (u need get your real source file paths)
                getImageUri.registerCallBack(new GetImageUri.Callback() {
                    @Override
                    public void callingBack() {
                        imgUrlList [getImageUri.getCount()] = getImageUri.getImageUri();
                        }
                    }
    
                    @Override
                    public void getReady() {
                        // here u can use your URLs
                        for (int k = 0; k < size; k ++) {
                            Log.d(TAG, "getReady: " + imgUrlList [k]);    
                    }
                });
                getImageUri.uploadImage(filePath, fileName, this.getContext(), imgListCount);
            }
        }
 类似资料:
  • 问题内容: 我正在使用以下代码将一个或多个文件上传到Firebase存储。上传完成后,将在控制台中记录downloadURL。 当所有文件都上传后,我想在forEach函数之外执行另一个函数。完成所有上传任务后,如何打印控制台日志? 问题答案: UploadTask对象的行为与promise一样,因为它们具有then()和catch()方法。因此,您可以将它们全部收集到一个数组中,并用于生成另一个

  • 我正在使用以下方法来保存信息。 我已经删除了一些用于访问数据库的代码行。 这是日志猫的描述。 E/StorageException:已发生StorageException。发生未知错误,请检查HTTP结果代码和内部异常以获取服务器响应。代码:-13000 HttpResult:0 E/AndroidRuntime:FATAL EXCEPTION:Firebase Storage-Upload-1

  • 我正在开发一个简单的博客应用程序,允许用户将照片从手机图库和描述上传到Firebase服务器。我正在尝试修改我的当前项目,以允许用户从照相机捕获照片并将其上载到firebase服务器。 目前,我能够将我捕获的图像显示到Image按钮中,但是我无法将我的图像发布到Firebase服务器(提交发布按钮不会对我的点击功能做出反应)。 我怀疑我的startPosting()函数中有错误,或者我没有正确编码

  • 我试图构建一个,它包括两个按钮,一个用于用相机拍照并上传到Firebase存储,另一个用于从Firebase存储下载图像并在上显示。 现在,我被上传功能卡住了。我可以把照片保存到应用程序目录中。我想上传保存的图片到Firebase存储。

  • 的控制台输出是正确的,我相信使用的是正确的。 上载的控制台输出如下: 然而,当我查看firebase存储时,新文件夹和图像不在那里。火药库没有变化。为什么它实际上不储存在仓库里?

  • 我从Firebase存储中获取图像,用相机拍照,或者从图书馆中挑选一张。当其中一个完成时,我有一个类来存储,以便在需要时使用它。 现在我需要将此图像上传到Firebase存储(修改或新建,无所谓)。Firebase允许我使用以下选项之一:或,每个选项分别需要或。 我怎么能把我的,并从它获得一个或用于上传? -- 或者,为了解决这个问题,当我从Firebase存储中检索图像时,如何获取图像的? 无论