Can't Disable Offline Data In Firestore
I just ran a few tests in an Android application to see how this works. Because Firestore is currently still in beta release
and the product might suffer changes any time, i cannot guarantee that this behaviour will still hold in the future.
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());
}
});
Regarding the code, is the same no matter if we're getting the data from the cache or you are connected to the servers.
When I'm online it prints:
isFromCache: false
When I'm offline, it prints:
isFromCache: true
So, for the moment, there is no way to stop the retrieval of the data from the cache while you are not connected to the server, as you cannot force the retrieval of the data from the cache while you're connected to the server.
If instead I use a listener:
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());
}
});
I get two prints when I'm online:
listener.isFromCache: true
listener.isFromCache: false
Firestore is desinged to retrieve data from the chache when the device is permanently offline or while your application temporarily loses its network connection and for the moment you cannot change this behaviour.
As a concusion, an API that does something like this, currently doesn't exist yet.
Edit: Unlike in Firebase, where to enable the offline persistence you need use this line of code:
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
In Firestore, for Android and iOS, offline persistence is enabled by default
.
Using the above line of code, means that you tell Firebase to create a local (internal) copy of your database so that your app can work even if it temporarily loses its network connection.
In Firestore we find the opposite, to disable persistence, we need to set the PersistenceEnabled
option to false
. This means that you tell Firestore not to create a local copy of your database on user device, which in term means that you'll not be able to query your database unless your are connected to Firebase servers. So without having a local copy of your database and if beeing disconected, an Exception will be thrown. That's why is a good practice to use the OnFailureListener
.
Update (2018-06-13): As also @TalBarda mentioned in his answer this is now possible starting with the 16.0.0 SDK version update. So we can achieve this with the help of the DocumentReference.get(Source source) and Query.get(Source source) methods.
By default,
get()
attempts to provide up-to-date data when possible by waiting for data from the server, but it may return cached data or fail if you are offline and the server cannot be reached. This behavior can be altered via the Source parameter.
So we can now pass as an argument to the DocumentReference
or to the Query
the source so we can force the retrieval of data from the server only
, chache only
or attempt server and fall back to the cache.
So something like this is now possible:
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
}
});
In this case, we force the data to be retrieved from the server only. If you want to force the data to be retrieved from the cache only, you should pass as an argument to the get()
method, Source.CACHE
. More informations here.
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) {
//...
}
});
For cache only, just change the code above to Source.CACHE
.
By default, both methods still attempt server and fall back to the cache.
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
.setPersistenceEnabled(false)
.build();
dbEventHome.setFirestoreSettings(settings);
By setting this it is fetching from server always.