当前位置: 首页 > 面试题库 >

如何避免使用缓存进行不必要的Firestore读取

朱季
2023-03-14
问题内容

我有按日期排序的旅行数据(大集合)列表。

现有行为

我将所有行程数据存储到SqlLite
Db中。对于添加的每个新数据,我通常都会收到fcm通知,并且使用上次更新的时间概念仅同步新添加的数据。这样,当cx打开应用程序时,他将始终从我的数据库中读取数据,从而节省了
读取网络 操作。

如何使用Firestore达到相同的目的?

需要考虑的几个问题:

  • Firestore get()始终尝试首先从服务器获取数据,即使我将CACHE添加到查询中,如何仅同步更新的文档
  • 在我的Recyler视图中,我希望按字段 日期 而不是lut(last-modified-time)对数据进行排序
  • 使用FireStore Snapshot Listener,我无法查询这么大的记录集。

问题答案:

Firestore get()始终尝试首先从SERVER获取数据,即使我将CACHE添加到查询中,如何仅同步更新的文档?

根据有关启用脱机数据的官方文档:

对于Android和iOS,默认情况下启用离线持久性。

因此,要使用离线持久性,您无需对代码进行任何更改(“添加”)即可使用和访问Cloud Firestore数据。

同样根据有关Query的get()方法的官方文档:

默认情况下,get()尝试通过等待来自服务器的数据来尽可能地提供最新数据,但是如果您离线并且无法访问服务器,它可能会返回缓存的数据或失败。可以通过Source参数更改此行为。

因此,这是正常的行为。从2018-06-13(16.0.0
SDK)开始,现在可以指定我们要从中获取数据的来源。我们可以借助DocumentReference.get(Source
source)和Query.get(Source
source)方法来实现。

正如你所看到的,我们现在可以作为参数传递给DocumentReference或给Query源,以便我们可以强制数据的检索从server onlychache only或尝试服务器,并回落到缓存中。

因此,现在可以执行以下操作:

yourDocRef.get(Source.SERVER).addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
    @Override
    public void onSuccess(DocumentSnapshot documentSnapshot) {
        //Get data from the documentSnapshot object
    }
});

在这种情况下,我们强制仅从服务器检索数据。如果要强制将只从缓存中检索数据,您应该作为参数传递给get()方法,Source.SERVER。更多信息在这里。

如果只想获取updated documents,则可以查看快照之间的更改。官方文档中的示例为:

db.collection("cities")
    .whereEqualTo("state", "CA")
    .addSnapshotListener(new EventListener<QuerySnapshot>() {
        @Override
        public void onEvent(@Nullable QuerySnapshot snapshots,
                @Nullable FirebaseFirestoreException e) {
        if (e != null) {
            Log.w(TAG, "listen:error", e);
            return;
        }

        for (DocumentChange dc : snapshots.getDocumentChanges()) {
            switch (dc.getType()) {
            case ADDED:
                Log.d(TAG, "New city: " + dc.getDocument().getData());
                break;
            case MODIFIED:
                Log.d(TAG, "Modified city: " + dc.getDocument().getData());
                break;
            case REMOVED:
                Log.d(TAG, "Removed city: " + dc.getDocument().getData());
                break;
            }
        }

        }
    });

看到每个特定情况的switch语句吗?第二种情况将帮助您仅获取更新的数据。

在我的Recyler视图中,我希望按字段日期而不是lut(last-modified-time)对数据进行排序

在这种情况下,您应该创建一个查询,该查询允许您按特定的日期属性对结果进行html" target="_blank">排序。假设您具有一个如下所示的数据库结构:

Firestore-root
   |
   --- items (collection)
        |
        --- itemId (document)
             |
             --- date: Oct 08, 2018 at 6:16:58 PM UTC+3
             |
             --- //other properties

像这样的查询将帮助您实现:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionRefference itemsRef = rootRef.collection("items");
Query query = itemsRef.orderBy("date", Query.Direction.ASCENDING);

使用FireStore Snapshot Listener,我无法查询这么大的记录集。

哦,可以。根据此答案,Firebase可以有效遍历数十亿个项目。该答案适用于Firebase实时数据库,但相同的原理也适用于Cloud Firestore。



 类似资料:
  • 我有一个Java servlet,它从android应用程序中获取一些数据,并使用以下代码将字符串数据返回给android应用程序。 然后使用以下方法将该值转换为字符串: 但是这样做之后,结果会添加一些不需要的字符(它们在菱形中以“?”的形式出现)附加到我从servlet传递的原始字符串中。我怎样才能避免这个?

  • 本文向大家介绍在React中如何避免不必要的render?相关面试题,主要包含被问及在React中如何避免不必要的render?时的应答技巧和注意事项,需要的朋友参考一下 shouldComponentUpdate、memoization、PureComponent

  • 我收集了2k份文件。我已经实现了分页,所以一次可以得到10个文档。文档如下所示: 要获取前10个元素,我使用以下查询: 要获得接下来的10个文档,我使用: 第一次打开应用程序时,我会滚动3页,这样总共会向缓存中添加30个文档。第二次打开应用时,我不想再次下载文档。由于我有字段,我可以查询: 这将返回所有新的/修改的文档,这很糟糕,因为如果添加了200个文档,我会为它们付费。换句话说,我花了200次

  • 我正在使用Guava缓存热数据。当缓存中不存在数据时,我必须从数据库中获取数据: 我的问题是当数据不存在于数据库中时,我希望它返回并且不做任何缓存。但Guava保存与缓存中的关键字,并抛出一个异常,当我得到它: com.google.common.cache.CacheLoader$InvalidCacheLoadExcION: CacheLoader为shisoft键返回null。 我们如何避免

  • 我有一个react功能组件,显示标签和帖子列表+几个静态文本/装饰。我使用钩子将当前选定的标记存储在一个状态中。通过使用Apollo的挂钩和变量获取帖子。用户应该能够选择一个标记,它将替换当前的状态-因此将使用新的变量重新运行。 我的问题是,为什么我的块一直在重新呈现,尽管我没有向它传递任何东西?还是我完全误解了react是如何工作的?

  • 我正在编写一些Swing应用程序,用于使用MigLayout进行测量。我试图消除不必要的差距。 我已经注意到,由于顶部的句子,差距是存在的。然而,当我删除它时,它看起来很好。 该问题在下图中可见: 我加句子的方式是: 我添加按钮的方式: 有人能帮我解释一下为什么会发生这种情况,以及我如何消除与现在句子的差距吗? ////////////编辑 我想使用我当前的基础架构,我已经在miglaway中启用