无法在Firestore中禁用脱机数据

Tal*_*rda 21 android firebase google-cloud-firestore

从我删除数据后,我Firestore Database需要花Android app一些时间才能意识到数据已被删除,并且我认为它是由于自动数据缓存而发生的.我的应用程序与离线使用无关,我想禁用此功能...

我在我的自定义中添加了这个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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在关闭互联网连接后将问题重新打开(当应用程序仍在运行时,在后台或不在时) - 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()) {
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

这是正常的行为吗?

有没有其他方法可以禁用数据缓存Cloud Firestore


编辑:

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

Ale*_*amo 6

我只是在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());
    }
});
Run Code Online (Sandbox Code Playgroud)

关于代码,无论我们是从缓存中获取数据还是连接到服务器,都是相同的。

当我在线时,它会打印:

isFromCache: false
Run Code Online (Sandbox Code Playgroud)

当我离线时,它会打印:

isFromCache: true
Run Code Online (Sandbox Code Playgroud)

因此,目前,在未连接到服务器时无法停止从缓存中检索数据,因为在连接到服务器时无法强制从缓存中检索数据。

相反,如果我使用侦听器:

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());
    }
});
Run Code Online (Sandbox Code Playgroud)

上网时会得到两张照片:

listener.isFromCache: true
listener.isFromCache: false
Run Code Online (Sandbox Code Playgroud)

当设备永久脱机或您的应用程序暂时失去网络连接,并且暂时无法更改此行为时,Firestore希望从缓存中检索数据。

作为一种脑震荡,目前尚不存在执行此类操作的API。

编辑:与Firebase不同,要在其中启用离线持久性,您需要使用以下代码行:

FirebaseDatabase.getInstance().setPersistenceEnabled(true);
Run Code Online (Sandbox Code Playgroud)

在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参数更改此行为。

所以我们现在可以作为参数传递给DocumentReference或给Query源,以便我们可以强制数据的检索从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
    }
});
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们强制仅从服务器检索数据。如果您想强制仅从缓存中检索数据,则应将用作参数传递给get()方法Source.CACHE。更多信息在这里


Tal*_*rda 5

According to Cloud Firestore 16.0.0 SDK update, there is now a solution to this problem:

在此处输入图片说明


You are now able to choose if you would like to fetch your data from the server only, or from the cache only, like this (an example for server only):

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

For cache only, just change the code above to Source.CACHE.


By default, both methods still attempt server and fall back to the cache.