firebase 无法在Firestore中禁用脱机数据

hgb9j2n6  于 2022-11-17  发布在  其他
关注(0)|答案(6)|浏览(148)

从我的Firestore Database删除数据后,我的Androidapp花了一些时间才意识到数据被删除,我认为这是由于自动数据缓存发生的。我的应用与离线使用无关,我想禁用此功能...
我已经在我的自定义Application Class中添加了以下内容:

import android.app.Application;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreSettings;

public class ApplicationClass extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        FirebaseFirestore db=FirebaseFirestore.getInstance();
        FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
                .setPersistenceEnabled(false)
                .build();
        db.setFirestoreSettings(settings);
    }
}

在关闭互联网连接然后重新打开后出现问题(* 应用仍在运行时,无论是否在后台运行 )-Firestore module似乎失去了与服务器的连接,并且执行了与预期相反的操作-而不是 * 停止 * 从该高速缓存中获取数据,而是 * 仅 * 从缓存中获取数据。
例如,调试这段代码将始终显示
*isFromCachetruedocumentSnapshot为空**(即使在server端-它不是空的):

usersRef.document(loggedEmail).collection("challenges_received").get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
    @Override
    public void onSuccess(QuerySnapshot documentSnapshots) {
        boolean isFromCache=documentSnapshots.getMetadata().isFromCache();
        if (!documentSnapshots.isEmpty()) {
        }
    }
});

这是正常行为吗?

是否有其他方法可以禁用Cloud Firestore中的数据缓存?

编辑:

在自定义Application Class中添加:FirebaseFirestore.setLoggingEnabled(flase);(而不是上面的代码)会得到相同的结果。

5ssjco0h

5ssjco0h1#

根据Cloud Firestore***16.0.0***SDK更新,现在有一个解决此问题的方案:

现在您可以选择是从 * 仅服务器 *、还是仅从 * 缓存 * 获取数据,如下所示(仅服务器示例):

DocumentReference documentReference= FirebaseFirestore.getInstance().document("example");
documentReference.get(Source.SERVER).addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
    @Override
    public void onSuccess(DocumentSnapshot documentSnapshot) {
            //...
    }
});

仅对于缓存,只需将上面的代码更改为Source.CACHE

默认情况下,这两种方法仍会尝试服务器并回退到该高速缓存.

bq3bfh9z

bq3bfh9z2#

我 刚刚 在 一 个 Android 应用 程序 中 运行 了 几 个 测试 , 看看 这 是 如何 工作 的 。 因为 Firestore 目前 仍 处于 beta release 中 , 产品 可能 随时 会 发生 变化 , 我 不 能 保证 这种 行为 在 未来 仍然 成立 。

db.collection("tests").document("fOpCiqmUjAzjnZimjd5c").get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
        DocumentSnapshot documentSnapshot = task.getResult();
        System.out.println("isFromCache: " + documentSnapshot.getMetadata().isFromCache());
    }
});

中 的 每 一 个
关于 代码 , 无论 我们 是 从 缓存 中 获取 数据 , 还是 连接 到 服务 器 , 都 是 一样 的 。
当 我 在线 时 , 它 会 打印 :

isFromCache: false

格式
当 我 离线 时 , 它 会 打印 :

isFromCache: true

格式
因此 , 目前 没有 办法 在 未 连接 到 服务 器 时 停止 从 缓存 中 检索 数据 , 因为 在 连接 到 服务 器 时 无法 强制 从 缓存 中 检索 数据 。
如果 我 使用 侦听 器 :

db.collection("tests").document("fOpCiqmUjAzjnZimjd5c").addSnapshotListener(new DocumentListenOptions().includeMetadataChanges(), new EventListener<DocumentSnapshot>() {
    @Override
    public void onEvent(DocumentSnapshot documentSnapshot, FirebaseFirestoreException e) {
        System.out.println("listener.isFromCache: " + documentSnapshot.getMetadata().isFromCache());
    }
});

格式
当 我 在线 时 , 我 得到 两 个 指纹 :

listener.isFromCache: true
listener.isFromCache: false

格式
Firestore 旨在 当 设备 永久 离线 或 您 的 应用 程序 暂时 失去 网络 连接 时 从 chache 中 检索 数据 , 而 此时 您 无法 更改 此 行为 。
作为 一 个 结论 , 一 个 API , 做 这样 的 事情 , 目前 还 不 存在 。

    • 编辑 : * * 与 Firebase 不同 , 在 Firebase 中 启用 离线 持久 性 需要 使用 以下 代码 行 :
FirebaseDatabase.getInstance().setPersistenceEnabled(true);

格式
在 Firestore 中 , 对于 Android 和 iOS , 离线 持久 性 为 enabled by default
使用 上面 的 代码 行 , 意味 着 您 告诉 Firebase 创建 数据 库 的 本地 ( 内部 ) 副本 , 以便 您 的 应用 程序 即使 暂时 失去 网络 连接 也 能 正常 工作 。
在 Firestore 中 , 我们 发现 相反 的 情况 , 要 禁用 持久 性 , 我们 需要 将 PersistenceEnabled 选项 设置 为 false 。 这 意味 着 您 告诉 Firestore 不要 在 用户 设备 上 创建 数据 库 的 本地 副本 , 这 意味 着 您 将 无法 查询 数据 库 , 除非 您 连接 到 Firebase 服务 器 。 因此 , 如果 没有 数据 库 的 本地 副本 , 并且 如果 断开 连接 ,这 就是 为什么 使用 OnFailureListener 是 一 个 很 好 的 实践 。

    • 更新 ( 2018 - 06 - 13 ) : * * 正如@TalBarda 在 他 的 回答 中 提到 的 , 现在 从 16.0.0 SDK 版本 更新 开始 , 这 是 可能 的 。 因此 , 我们 可以 通过 DocumentReference . get ( Source source ) 和 Query . get ( Source source ) 方法 来 实现 这 一 点 。

默认 情况 下 , get() 通过 等待 来自 服务 器 的 数据 来 尝试 尽 可能 提供 最 新 数据 , 但 如果 您 处于 脱机 状态 且 无法 访问 服务 器 , 则 它 可能 会 返回 缓存 数据 或 失败 。 可以 通过 Source 参数 更改 此 行为 。
因此 , 我们 现在 可以 将 源 代码 作为 参数 传递 给 DocumentReferenceQuery , 这样 我们 就 可以 强制 从 server onlychache only 或 尝试 服务 器 检索 数据 , 并 回 退到 缓存 。
所以 现在 这样 的 事情 是 可能 的 :

FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference docIdRef = db.collection("tests").document("fOpCiqmUjAzjnZimjd5c");
docIdRef.get(Source.SERVER).addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
    @Override
    public void onSuccess(DocumentSnapshot documentSnapshot) {
        //Get data from the documentSnapshot object
    }
});

格式
在 这种 情况 下 , 我们 强制 只 从 服务 器 上 检索 数据 。 如果 你 想 强制 只 从 缓存 中 检索 数据 , 你 应该 将 一 个 参数 传递 给 get() 方法 , Source.CACHE 。 更多 信息 here

svdrlsy4

svdrlsy43#

FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder() .setPersistenceEnabled(false) .build(); dbEventHome.setFirestoreSettings(settings);
通过设置此项,它将始终从服务器获取。

wgxvkvu9

wgxvkvu94#

// Enable Firestore logging
    FirebaseFirestore.setLoggingEnabled(flase);
// Firestore
    mFirestore = FirebaseFirestore.getInstance();

一般来说:Firebase客户端会尽量减少下载数据的次数,但同时也会尽量减少使用的内存/磁盘空间。
确切的行为取决于许多因素,例如另一个侦听器是否在该位置保持活动状态,以及是否使用磁盘持久性。如果有两个侦听器用于相同(或重叠)的数据,则更新将只下载一次。但是,如果删除某个位置的最后一个侦听器,则该位置的数据将从(内存和/或磁盘)高速缓存中删除。
如果没有看到完整的代码片段,很难判断在您的情况下会发生什么。
或者:您可以通过启用Firebase的日志记录[Firebase setLoggingEnabled:YES]来亲自检查;

请为FireBase数据库尝试此操作

mDatabase.getReference().keepSynced(false);      
      FirebaseDatabase.getInstance().setPersistenceEnabled(false);
zhte4eai

zhte4eai5#

在Kotlin;

val settings = FirebaseFirestoreSettings.Builder()
            with(settings){
                isPersistenceEnabled = false
}
Firebase.firestore.firestoreSettings = settings.build()
9rnv2umw

9rnv2umw6#

在Kotlin:

val db:FirebaseFirestore = Firebase.firestore
        val settings = firestoreSettings {
            isPersistenceEnabled = false
        }
        db.firestoreSettings = settings

相关问题