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

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

问题描述

我有一个按日期排序的行程数据(大集)列表.

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

现有行为

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

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(last-modified-time)
  • 使用 FireStore 快照侦听器,我无法查询如此大的记录集.
  • 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 sync 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 的官方文档 get() 方法:

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) 开始,现在可以指定我们想要获取数据的来源.我们可以在 DocumentReference.get(Source source)Query.get(Source source) 方法.

So this is normal behavior. 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 onlycache 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, cache only or attempt server and fall back to the cache.

所以现在这样的事情是可能的:

So something like this is now possible:

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

在这种情况下,我们强制仅从服务器检索数据.如果您想强制只从缓存中检索数据,您应该将其作为参数传递给 get() 方法,Source.CACHE.更多信息请此处.我也写过一篇文章,可以帮助理解更清晰的概念:

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.CACHE. More informations here. I also wrote an article that can help understand more clear the concept:

如果您只想获取更新的文档,您可以查看快照之间的变化.官方文档中的一个例子是:

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(last-modified-time)

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

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

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天全站免登陆