无法在 Firestore 中禁用脱机数据

从中删除数据后,我需要一些时间才能意识到数据已被删除,并且我假设这是由于自动数据缓存而发生的。我的应用程序与离线使用无关,我想禁用此功能...Firestore DatabaseAndroidapp

我已经在我的自定义中添加了这个: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

例如,调试此代码将始终显示 isFromCachedocumentSnapshot 为空(即使该代码位于侧面 - 它不是空的):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


编辑:

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


答案 1

根据 16.0.0 SDK 更新,现在有一个解决方案可以解决这个问题:Cloud Firestore

enter image description here


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

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

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


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


答案 2

我刚刚在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中,我们发现相反的情况是,要禁用持久性,我们需要将选项设置为。这意味着您告诉Firestore不要在用户设备上创建数据库的本地副本,这意味着除非您连接到Firebase服务器,否则您将无法查询数据库。因此,如果没有数据库的本地副本,并且如果 beeing disconeced,将引发异常。这就是为什么使用 .PersistenceEnabledfalseOnFailureListener

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

默认情况下,尝试通过等待来自服务器的数据来尽可能提供最新数据,但如果处于脱机状态且无法访问服务器,则可能会返回缓存的数据或失败。可以通过 Source 参数更改此行为。get()

因此,我们现在可以作为参数传递给源或源,以便我们可以强制从 或 尝试服务器检索数据并回退到缓存。DocumentReferenceQueryserver 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


推荐