使用 Firebase Storage 和 Firebase Firestore 创建离线第一个应用程序的最佳方法是啥? #AskFirebase

Posted

技术标签:

【中文标题】使用 Firebase Storage 和 Firebase Firestore 创建离线第一个应用程序的最佳方法是啥? #AskFirebase【英文标题】:What is the best way to create offline first application with Firebase Storage and Firebase Firestore? #AskFirebase使用 Firebase Storage 和 Firebase Firestore 创建离线第一个应用程序的最佳方法是什么? #AskFirebase 【发布时间】:2020-04-23 07:24:48 【问题描述】:

首先我是 Firebase 的新手 :)

我找不到说明如何使用 Firebase Storage 和 Firebase Firestore 创建离线优先移动应用的教程或示例。 我使用 Firestore 来保存有关项目的数据:id、name、image。 我使用存储来保存图像并将这些图像与 Firestore 中的项目链接。 当手机连接到互联网时,一切都很好,但我不确定在设备离线时处理添加项目的最佳方法是什么。

我能想到的唯一好的解决方案:

    将项目的图像道具设置为本地文件 url,以便图像可以显示在我的回收站视图中。 同时开始上传项目和图片。 保留图像sessionUri 和本地文件路径,以便稍后恢复任务。 检测连接变化并恢复图像任务(如果有)。 图片上传完成后,获取下载地址和firestore中的更新项目。然后清除持久化图像任务。

我真的期待 Firebase 客户端库能够开箱即用地处理这样一个微不足道的用例。

MCVE:

public void addImageOnClick(final View view) 
    final Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(intent, 123);


@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent intent) 
    super.onActivityResult(requestCode, resultCode, intent);
    if (requestCode == 123) 
        save("id1", "name1", intent.getData());
    


private void save(final String id, final String name, final Uri imageUri) 
    final Map<String, Object> item = new HashMap<>();
    item.put("id", id);
    item.put("name", name);
    FirebaseStorage.getInstance()
            .getReference("items")
            .child(id)
            .putFile(imageUri)
            .continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() 
                @Override
                public Task<Uri> then(final Task<UploadTask.TaskSnapshot> task) throws Exception 
                    return task.getResult()
                            .getMetadata()
                            .getReference()
                            .getDownloadUrl();
                
            )
            .continueWith(new Continuation<Uri, Void>() 
                @Override
                public Void then(final Task<Uri> task) throws Exception 
                    item.put("image", task.getResult().toString());
                    FirebaseFirestore.getInstance()
                            .collection("items")
                            .document(id)
                            .set(item);
                    return null;
                
            )
            .continueWith(new Continuation<Void, Void>() 
                @Override
                public Void then(final Task<Void> task) throws Exception 
                    Toast.makeText(MainActivity.this, String.valueOf(task.isSuccessful()), Toast.LENGTH_LONG).show();
                    return null;
                
            );

【问题讨论】:

乍一看,您的方法中的步骤对我来说似乎是正确的。您在实施过程中遇到问题吗? 我想知道是否有可以为我执行此操作的 firebase api,或者是否有推荐的方法来执行此操作。不幸的是,firebase 存储客户端库甚至不支持像 firebase firestore 这样的离线模式,我需要手动恢复上传。我很确定这是 Firebase 存储最常见的用法:上传图像并将它们与 firestore 链接,如果它是客户端库的一部分,那就太好了。 我也在使用相同的组合。你有什么解决办法吗? 【参考方案1】:

这实际上并不是一个可以用单个 API 解决的“小问题”。

您在这里处理两种不同的产品 - Cloud Storage 和 Firestore。每个都有自己的、完全独立的 API 和存储数据的方法。如果您愿意,它们可以单独使用或一起使用。由于您选择将它们一起使用(这很棒!),您仍然必须编写代码来独立处理它们,同时还必须使用您提出的某种方案将它们粘合在一起。看起来你知道你在做什么。它并没有变得更简单。

【讨论】:

我也在使用相同的组合。你有什么解决办法吗?

以上是关于使用 Firebase Storage 和 Firebase Firestore 创建离线第一个应用程序的最佳方法是啥? #AskFirebase的主要内容,如果未能解决你的问题,请参考以下文章

从 Fire Storage 检索图像,但是如果图像不存在,则应用程序崩溃

“同时”使用 Firebase Storage 和 Cloud Firestore

使用 Firebase Storage 和 Firebase Firestore 创建离线第一个应用程序的最佳方法是啥? #AskFirebase

Firebase学习手记-Storage

RecyclerView 和 Firebase Storage 快速滚动 ExoPlayer 异常

使用 Cloud Functions for Firebase 和 @google-cloud/storage 删除图像时出现问题