Java Can';t禁用Firestore中的脱机数据

Java Can';t禁用Firestore中的脱机数据,java,android,firebase,google-cloud-firestore,Java,Android,Firebase,Google Cloud Firestore,从我的Firestore数据库中删除数据后,我的Android应用程序花了一段时间才意识到数据已被删除,我认为这是由于自动数据缓存造成的。我的应用程序与脱机使用无关,我想禁用此功能 我已经在我的自定义应用程序类中添加了以下内容: import android.app.Application; import com.google.firebase.firestore.FirebaseFirestore; import com.google.firebase.firestore.FirebaseFi

从我的
Firestore数据库
中删除数据后,我的
Android
应用程序
花了一段时间才意识到数据已被删除,我认为这是由于自动数据缓存造成的。我的应用程序与脱机使用无关,我想禁用此功能

我已经在我的自定义
应用程序类中添加了以下内容:

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模块似乎与服务器断开连接,并执行与预期操作相反的操作-而不是停止从缓存获取数据,它只从缓存中获取数据。

  mDatabase.getReference().keepSynced(false);      
      FirebaseDatabase.getInstance().setPersistenceEnabled(false);
例如,调试此代码将始终显示
isFromCache
true
,并且
文档快照
为空(即使
服务器端的
不是空的):

usersRef.document(loggedEmail).collection(“challenges_received”).get().addOnSuccessListener(new OnSuccessListener()){
@凌驾
成功时公共无效(QuerySnapshot文档快照){
布尔值isFromCache=documentSnapshots.getMetadata().isFromCache();
如果(!documentSnapshots.isEmpty()){
}
}
});
这是正常行为吗?

  mDatabase.getReference().keepSynced(false);      
      FirebaseDatabase.getInstance().setPersistenceEnabled(false);
是否有其他方法禁用
Cloud Firestore中的数据缓存


编辑:

添加:
FirebaseFirestore.setLoggingEnabled(flase)应用程序类中的code>(而不是上面的代码)给出相同的结果

// Enable Firestore logging
    FirebaseFirestore.setLoggingEnabled(flase);
// Firestore
    mFirestore = FirebaseFirestore.getInstance();
一般情况下:Firebase客户端会尽量减少下载数据的次数。但它也试图最小化所使用的内存/磁盘空间

确切的行为取决于许多因素,例如另一个侦听器是否在该位置保持活动状态,以及您是否正在使用磁盘持久性。如果有两个侦听器用于相同(或重叠)数据,则更新将只下载一次。但是,如果删除某个位置的最后一个侦听器,则该位置的数据将从(内存和/或磁盘)缓存中删除

如果看不到完整的代码,就很难判断您的案例会发生什么

或者:您可以通过启用Firebase的日志来检查自己
[Firebase setLoggingEnabled:YES]

在FireBase数据库中尝试此操作

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

我只是在Android应用程序中运行了一些测试,看看这是如何工作的。由于Firestore目前仍处于测试版
,并且产品可能随时发生变化,因此我无法保证这种行为在未来仍将持续

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());
    }
});
Firestore设计用于在设备永久脱机或应用程序暂时失去网络连接且暂时无法更改此行为时从chache检索数据

作为一个震荡,一个类似这样的API,目前还不存在

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

FirebaseDatabase.getInstance().setPersistenceEnabled(true);
在Firestore中,对于Android和iOS,默认情况下启用脱机持久性

使用上述代码行意味着您告诉Firebase创建数据库的本地(内部)副本,以便您的应用程序即使暂时失去网络连接也可以工作

在Firestore中,我们发现相反的情况,要禁用持久性,我们需要将
PersistenceEnabled
选项设置为
false
。这意味着您告诉Firestore不要在用户设备上创建数据库的本地副本,这意味着您将无法查询数据库,除非您的数据库连接到Firebase服务器。因此,在没有数据库的本地副本的情况下,如果being被断开,将引发异常。这就是为什么使用
OnFailureListener
是一种很好的做法

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

默认情况下,
get()。可以通过源参数更改此行为

因此,我们现在可以将其作为参数传递给源文件的
文档引用
查询
,这样我们就可以强制仅从
服务器
仅查询
检索数据,或尝试服务器并返回缓存

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

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
    }
});
FirebaseFirestore db=FirebaseFirestore.getInstance();
DocumentReference docIdRef=db.collection(“tests”).document(“fOpCiqmUjAzjnZimjd5c”);
docIdRef.get(Source.SERVER).addOnSuccessListener(新的OnSuccessListener()){
@凌驾
成功时公共无效(文档快照文档快照){
//从documentSnapshot对象获取数据
}
});

在这种情况下,我们强制只从服务器检索数据。如果要强制仅从缓存检索数据,应将其作为参数传递给
get()
方法
Source.cache
。更多信息。

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


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