Après la suppression des données de mon Firestore Database
, il faut un certain temps à ma Android
app
pour comprendre que les données ont été supprimées, et je suppose que cela est dû au cache de données automatique. Mon application n'a rien à voir avec une utilisation hors ligne et j'aimerais désactiver cette fonctionnalité ...
J'ai ajouté ceci dans mon Application Class
personnalisé:
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);
}
}
Le problème survient après avoir désactivé la connexion Internet et l'avoir réactivée (alors que l'application est toujours en cours d'exécution, en arrière-plan ou non) - le Firestore module
semble perdre la connexion au serveur et rend l'opération inverse. que celui prévu - au lieu de stop en prenant des données du cache, il prend des données du cache seulement.
Par exemple, le débogage de ce code indiquera toujours queisFromCache
EST true
etdocumentSnapshot
est vide (même si cela du côté server
- ce n'est pas vide):
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()) {
}
}
});
Est-ce un comportement normal?
Existe-t-il un autre moyen de désactiver le cache de données dans Cloud Firestore
?
MODIFIER:
L'ajout de FirebaseFirestore.setLoggingEnabled(flase);
(au lieu du code ci-dessus) dans le Application Class
personnalisé donne le même résultat.
Je viens de lancer quelques tests dans une application Android pour voir comment cela fonctionne. Comme Firestore est toujours dans beta release
et que le produit peut subir des modifications à tout moment, je ne peux pas garantir que ce problème se maintiendra dans le futur.
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());
}
});
En ce qui concerne le code, est le même, que nous obtenions les données du cache ou que vous soyez connecté aux serveurs.
Quand je suis en ligne, il imprime:
isFromCache: false
Lorsque je suis hors ligne, il affiche:
isFromCache: true
Ainsi, pour le moment, il n’existe aucun moyen d’arrêter la récupération des données du cache tant que vous n’êtes pas connecté au serveur, car vous ne pouvez pas forcer la récupération des données du cache lorsque vous êtes connecté au serveur.
Si à la place j'utilise un auditeur:
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());
}
});
Je reçois deux copies lorsque je suis en ligne:
listener.isFromCache: true
listener.isFromCache: false
Firestore est conçu pour extraire les données de la procédure lorsque le périphérique est hors ligne ou que votre application perd temporairement sa connexion réseau. Pour le moment, vous ne pouvez pas modifier ce comportement.
En tant que confusion, une API qui fait quelque chose comme ceci n'existe pas encore.
Edit: Contrairement à Firebase, pour activer la persistance hors connexion, utilisez cette ligne de code:
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
Dans Firestore, pour Android et iOS, la persistance hors connexion est enabled by default
.
L'utilisation de la ligne de code ci-dessus signifie que vous demandez à Firebase de créer une copie locale (interne) de votre base de données afin que votre application puisse fonctionner même si elle perd temporairement sa connexion réseau.
Dans Firestore, nous trouvons le contraire: pour désactiver la persistance, nous devons définir l’option PersistenceEnabled
sur false
. Cela signifie que vous dites à Firestore de ne pas créer de copie locale de votre base de données sur la machine utilisateur, ce qui signifie que vous ne pourrez plus interroger votre base de données à moins que vous ne soyez connecté à des serveurs Firebase. Donc, sans avoir une copie locale de votre base de données et si vous êtes déconnecté, une exception sera levée. C’est pourquoi il est recommandé d’utiliser OnFailureListener
.
Update (2018-06-13): Comme @TalBarda l'a également mentionné dans sa réponse, il est désormais possible de démarrer à partir de la mise à jour de la version 16.0.0 du SDK. Nous pouvons donc y parvenir à l’aide des méthodes DocumentReference.get (Source source) et Query.get (Source source) .
Par défaut,
get()
tente de fournir des données à jour autant que possible en attendant des données du serveur, mais il peut renvoyer des données en cache ou échouer si vous êtes hors ligne et que le serveur ne peut pas être atteint. Ce comportement peut être modifié via le paramètre Source.
Nous pouvons donc maintenant passer en argument à la variable DocumentReference
ou à la source Query
afin que nous puissions forcer l'extraction des données à partir du server only
, chache only
ou du serveur de tentatives et revenir au cache.
Donc, quelque chose comme ceci est maintenant 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
}
});
Dans ce cas, nous forçons les données à extraire du serveur uniquement. Si vous souhaitez forcer l'extraction des données à partir du cache uniquement, vous devez passer en tant qu'argument à la méthode get()
, Source.CACHE
. Plus d'informations ici .
Selon Cloud Firestore
16.0.0 mise à jour du SDK, il existe maintenant une solution à ce problème:
Vous êtes maintenant en mesure de choisir si vous souhaitez extraire vos données du serveur uniquement, ou du cache uniquement, comme ceci (exemple pour le serveur uniquement) :
DocumentReference documentReference= FirebaseFirestore.getInstance().document("example");
documentReference.get(Source.SERVER).addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
//...
}
});
Pour le cache uniquement, changez simplement le code ci-dessus en Source.CACHE
.
Par défaut, les deux méthodes tentent toujours le serveur et retombent dans le cache.
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
.setPersistenceEnabled(false)
.build();
dbEventHome.setFirestoreSettings(settings);
En paramétrant ceci, il récupère toujours le serveur.
// Enable Firestore logging
FirebaseFirestore.setLoggingEnabled(flase);
// Firestore
mFirestore = FirebaseFirestore.getInstance();
En général: le client Firebase tente de réduire le nombre de téléchargements de données. Mais il essaie également de minimiser la quantité de mémoire/d’espace disque qu’il utilise.
Le comportement exact dépend de nombreux facteurs, par exemple si un autre écouteur est resté actif sur cet emplacement et si vous utilisez la persistance de disque. Si vous avez deux écouteurs pour les mêmes données (ou qui se chevauchent), les mises à jour ne seront téléchargées qu'une fois. Mais si vous supprimez le dernier écouteur pour un emplacement, les données de cet emplacement sont supprimées du cache (mémoire et/ou disque).
Sans voir un code complet, il est difficile de dire ce qui se passera dans votre cas.
Vous pouvez aussi vérifier par vous-même en activant la journalisation de Firebase [Firebase setLoggingEnabled:YES]
;
essayez ceci Pour FireBase DataBase
mDatabase.getReference().keepSynced(false);
FirebaseDatabase.getInstance().setPersistenceEnabled(false);