Impossible de désactiver les données hors ligne dans Firestore

après avoir supprimé des données de mon Firestore Database, il prend mon Androidapp un certain temps pour se rendre compte que les données ont été supprimées, et je suppose que cela se passe en raison du cache de données automatique. Mon application n'a rien à voir avec l'utilisation hors connexion et je voudrais désactiver cette fonctionnalité...

j'ai ajouté ceci dans mon custom 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);
    }
}

le problème survient après que la connexion internet a été désactivée et que la connexion a été rallumée (alors que l'application est toujours en cours d'exécution, dans le arrière-plan ou pas) -Firestore module semble perdre la connexion au serveur, et il fait l'opération inverse que celui souhaité - au lieu de arrêt prenant les données du cache, il prend les données du cache .

par exemple, déboguer ce code montrera toujours que isFromCachetrue et documentSnapshot est vide (même si sur le server côté - 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()) {
        }
    }
});

ce comportement est-il normal?

Est-il une autre façon de désactiver le cache de données dans Cloud Firestore?


EDIT:

Ajout de: FirebaseFirestore.setLoggingEnabled(flase); (au lieu du code ci-dessus) dans le custom Application Class donne le même résultat.

19
demandé sur Tal Barda 2017-10-23 19:24:21

3 réponses

je viens de faire quelques tests dans une application Android pour voir comment cela fonctionne. Parce que Firestore est toujours en beta release et le produit pourrait subir des changements à tout moment, je ne peux pas garantir que ce comportement se maintiendra à l'avenir.

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 peu importe si nous obtenons les données du cache ou si vous êtes connectés aux serveurs.

Quand je suis en ligne il affiche:

isFromCache: false

quand je suis hors ligne, il imprime:

isFromCache: true

donc, pour le moment, il n'y a aucun moyen d'arrêter la récupération des données du cache tant que vous n'êtes pas connectés au serveur, car vous ne pouvez pas forcer la récupération des données du cache tant que vous êtes connectés au serveur.

Si j'utilise à la place un 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());
    }
});

j'obtiens deux impressions quand je suis en ligne:

listener.isFromCache: true
listener.isFromCache: false

Firestore est conçu pour extraire des données du chache lorsque l'appareil est déconnecté de façon permanente ou alors que votre application perd temporairement sa connexion réseau et pour le moment vous ne pouvez pas changer ce comportement.

en tant que concusion, une API qui fait quelque chose comme ça, n'existe pas encore.

Edit: contrairement à Firebase, où pour activer la persistance hors ligne vous devez utiliser cette ligne de code:

FirebaseDatabase.getInstance().setPersistenceEnabled(true);

dans Firestore, pour Android et iOS, la persistance hors ligne est enabled by default.

en utilisant la ligne ci-dessus de code, signifie que vous dites à 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 avons besoin de mettre le PersistenceEnabled option false. Cela signifie que vous dites à Firestore de ne pas créer une copie locale de votre base de données sur le périphérique utilisateur, ce qui signifie à terme que vous ne serez pas en mesure d'interroger votre base de données à moins que votre sont connectés à Firebase serveur. Donc, sans avoir une copie locale de votre base de données et en cas de non-détection, une Exception sera lancée. C'est pourquoi c'est une bonne pratique d'utiliser le OnFailureListener.

mise à Jour (2018-06-13): comme @TalBarda l'a également mentionné dans sa réponse, ceci est maintenant possible à partir de la mise à jour de la version 16.0.0 SDK. Nous pouvons donc y parvenir avec l'aide de classe documentreference.get (Source) et Requête.get (Source) méthode.

Par défaut, get() tente de fournir des données à jour lorsque c'est possible en attendant les données du serveur, mais il peut retourner des données cachées 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.

donc nous pouvons maintenant passer comme argument au DocumentReference ou <à la!--14--> la source de sorte que nous pouvons forcer la récupération de données à partir de la server only,chache only ou essayer le serveur et revenir à la cache.

alors quelque chose comme ça 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 forcons les données à être récupérées à partir du serveur seulement. Si vous voulez forcer la récupération des données à partir du cache, vous devez passer en argument à l' get() méthode Source.SERVER. Plus d'infos ici.

3
répondu Alex Mamo 2018-06-13 17:48:43

Selon Cloud Firestore16.0.0 mise à jour SDK, il y a maintenant une solution à ce problème:

enter image description here


vous pouvez maintenant choisir si vous souhaitez récupérer vos données à partir du serveur,oucache, comme ceci (un exemple de 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 seulement, changez le code ci-dessus en Source.CACHE.


par défaut, les deux méthodes tentent toujours le serveur et retombent dans le cache.

1
répondu Tal Barda 2018-05-04 07:05:32
// Enable Firestore logging
    FirebaseFirestore.setLoggingEnabled(flase);
// Firestore
    mFirestore = FirebaseFirestore.getInstance();

en général: le client Firebase essaie de minimiser le nombre de fois où il télécharge des données. Mais il essaie aussi de minimiser la quantité d'espace mémoire/disque qu'il utilise.

le comportement exact dépend de beaucoup de choses, comme si l'autre auditeur est resté actif à cet endroit 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 seule fois. Mais si vous supprimez le dernier auditeur pour un emplacement, les données pour cet emplacement sont retirées du cache (mémoire et/ou disque).

sans voir un morceau de code complet, il est difficile de dire ce qui va se passer dans votre cas.

alternativement: vous pouvez vérifier vous-même en activant la journalisation de Firebase [Firebase setLoggingEnabled:YES];

essayez ceci Pour FireBase Base de données

  mDatabase.getReference().keepSynced(false);      
      FirebaseDatabase.getInstance().setPersistenceEnabled(false);
0
répondu Atif AbbAsi 2017-11-15 12:44:18