如何避免使用Cache进行不必要的Firestore读取 [英] How to avoid unnecessary Firestore reads with Cache

查看:113
本文介绍了如何避免使用Cache进行不必要的Firestore读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a list of trips data (Large Sets) ordered by date.

现有行为

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

I store all the trips data into SqlLite Db. For every new data added, I used to get a fcm notification and I synced only the new added data using last updated time concept. This way when ever an cx opens the app, he will always read the data from my DB, Hence saving read and network operations.

我如何在Firestore中实现相同目标?

要考虑的几个问题:

  • Firestore get()始终尝试首先从SERVER获取数据,即使我将CACHE添加到查询中,我如何也只能同步更新的文档
  • 在我的Recyler视图中,我希望数据按字段日期而不是lut(上次修改时间)
  • 排序
  • 使用FireStore Snapshot Listener,我无法查询这么大的记录集.
  • Firestore get() always tries to get the data first from SERVER, even if i add CACHE to my query, how can i synced only the updated document
  • In my Recyler View I want the data to be order by a field date not by lut(last-modified-time)
  • With FireStore Snapshot Listener i can't query such a large record set.

推荐答案

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

Firestore get() always tries to get the data first from SERVER, even if I add CACHE to my query, how can I synced only the updated document?

根据有关启用离线数据的官方文档:

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

For Android and iOS, offline persistence is enabled by default.

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

So to use offline persistence, you don't need to make ("add") any changes to your code in order to be able to use and access Cloud Firestore data.

还根据有关Query的官方文档

Also according to the official documentation regarding Query's get() method:

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

By default, get() attempts to provide up-to-date data when possible by waiting for data from the server, but it may return cached data or fail if you are offline and the server cannot be reached. This behavior can be altered via the Source parameter.

这是正常的行为.从2018-06-13(16.0.0 SDK)开始,现在可以指定我们要从中获取数据的来源.我们可以借助

So this is the normal behaviour. Starting with 2018-06-13 (16.0.0 SDK) is now possible to specify the source from which we want to get data. We can achieve this with the help of the DocumentReference.get(Source source) and Query.get(Source source) methods.

如您所见,我们现在可以将参数作为参数传递给DocumentReferenceQuery源,以便我们可以强制从server onlychache only检索数据或尝试服务器摔倒回到缓存.

As you can see, we can now pass as an argument to the DocumentReference or to the Query the source so we can force the retrieval of data from the server only, chache only or attempt server and fall back to the cache.

所以现在可以这样:

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

在这种情况下,我们强制仅从服务器检索数据.如果要强制仅从缓存中检索数据,则应将其作为参数传递给get()方法Source.SERVER. 此处.

In this case, we force the data to be retrieved from the server only. If you want to force the data to be retrieved from the cache only, you should pass as an argument to the get() method, Source.SERVER. More informations here.

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

If you want to get only updated documents, you can view changes between snapshots. An example from the official documentation would be:

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语句吗?第二种情况将帮助您仅获取更新的数据.

See the switch statement for every particular case? The second case will help you get only the updated data.

在我的Recyler视图中,我希望按字段日期而不是lut(上次修改时间)对数据进行排序

In my Recyler View I want the data to be order by a field date not by lut(last-modified-time)

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

In this case you should create a query that allow you order the results by a specific date property. Assuming you have a database structure that looks like this:

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

like这样的查询将帮助您实现这一目标:

The query like will help you achieve this:

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

是也是建议的一种向Cloud Firestore数据库添加时间戳的方法.

This is also a recommended way on which you can add a timestamp to a Cloud Firestore database.

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

With FireStore Snapshot Listener i can't query such a large record set.

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

Oh, yes you can. According this answer, Firebase can effectively loop through billions items. This answer is for Firebase realtime database but same principles apply to Cloud Firestore.

这篇关于如何避免使用Cache进行不必要的Firestore读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆