【问题标题】:How to make sure Firestore cached data is up to date in Android?如何确保 Firestore 缓存的数据在 Android 中是最新的?
【发布时间】:2021-01-09 14:53:32
【问题描述】:

我正在制作一个 Android 应用程序,其中我在布局顶部有 TabLayout,它负责过滤我的列表。在第一次启动时,我尝试使用 Source.CACHE 从缓存中获取数据,然后如果没有找到结果,我会使用 Source.SERVER。我已经制定了一些算法来跟踪顶部和机器人缓存的文档,并基于它们从服务器下载额外的数据,不管查询。这工作正常,但是如果其他人编辑了其中一些缓存文档,我的应用程序将加载旧数据,这很好。 我使用 get() 只获取一次数据,因为我不希望在用户滚动时弹出新项目。

那么我将如何实现我的缓存数据与最新数据保持同步呢? 我找到了一些“解决方案”,据说如果不下载数据是不可能的,但是可以通过在缓存数据上设置一次 EventListener 来检索更新的数据并只读更改的文档,因为它当您想要实时更新时正在完成?

我当前的onCompleteListener

 @Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {

    if(task.isSuccessful())
    {
        boolean isEmpty = task.getResult().isEmpty();
        if(isEmpty && task.getResult().getMetadata().isFromCache()) {
            query.limit(JobModel.LIMIT).get(Source.SERVER).addOnCompleteListener(this);
        }
        else
        {
            for(DocumentSnapshot documentChange : task.getResult().getDocuments()) {
                JobModel jobModel = documentChange.toObject(JobModel.class);
                jobModel.setId(documentChange.getId());
                jobLoading.getJobModels().add(jobModel);
            }

            int querySnapshotSize = task.getResult().size();

            //This saves first and last Cached documents - ONLY if its from Cache and has at least 1 item - SPECIAL CASE - FROM CASE
            if(task.getResult().getMetadata().isFromCache() && querySnapshotSize > 0)
                onLastVisibleJobCallback.setCachedEdgeDocuments(task.getResult().getDocuments().get(0), task.getResult().getDocuments().get(querySnapshotSize-1));

           
            if(querySnapshotSize < JobModel.LIMIT)
                onLastJobReachedCallback.setReached(true);
            else
            {
                DocumentSnapshot lastVisibleProduct = task.getResult().getDocuments().get(querySnapshotSize - 1);
                onLastVisibleJobCallback.setLastVisibleJob(lastVisibleProduct);
            }

            Log.d("LIVE_DATA", "New jobs job LOADED, size: " + jobLoading.getJobModels().size());
            setValue(jobLoading);           
        }
    }
    else
        Log.d("LIVE_DATA", task.getException().getMessage());
}

【问题讨论】:

  • 我认为这 article 可能会有所帮助。
  • 很高兴收到您的来信,我实际上已经阅读了那篇文章,但我不知道如何实现分页。因为,当通过 json 将 DocumentSnapshot 放入 SharedPreferences 时,我得到了 StackOverflowError 。困扰我的第二件事是我需要对“lastModified”使用查询,然后我不能对我需要的其他字段使用查询,例如。 “价格”..

标签: android firebase google-cloud-firestore


【解决方案1】:

如果您想控制缓存的更新时间,您需要:

  1. 在数据中存储一个值,指示上次更新的时间。我通常称之为lastUpdated
  2. 跟踪您的应用上次加载数据的时间,这些数据存储在名为 lastLoaded 的 SharedPreference 之类的地方。
  3. 当您想要更新 lastUpdated &gt;= lastLoaded 所在的文档的缓存时运行查询,然后将 lastLoaded 更新为当前时间。

确实下载了更新的数据,这也意味着确实是“不下载数据就不可能[更新缓存]”。

【讨论】:

  • 好的,如您的回答中的 3. 所述,Query 只会从 lastLoaded 下载更改过的文档,但我怎么知道(如果 Firestore 不自行处理)哪些文档要在之后更新下载更新?
  • 我不确定“更新”是什么意思,但我希望您必须处理所有下载的文档(因此处理所有查询结果)。
  • “更新”意味着设置新的(更改的)值。处理这些数据我可能会在我的回收站视图中得到正确的结果,但是下次用户进入应用程序时,他不会仍然得到旧值(更新前),因为它的值在 Firestore 缓存中从未更改过?我的意思是我有点困惑 Firestore 以何种方式处理数据和缓存
  • 如果您通过查询获得更新的数据,它也总是在本地缓存中更新。我描述的方法已经过尝试和测试,所以我建议尝试一下。
  • 我想我明白了,谢谢您的宝贵时间。
猜你喜欢
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-16
  • 1970-01-01
  • 2018-01-05
  • 1970-01-01
相关资源
最近更新 更多