2017-10-10 3 views
2

Tout commence à explorer le stockage Firestore et la première chose à faire - lire un petit document simple dans mon application Android par clé de document (authentifié avec Google, mais ce n'est probablement pas important). Voici un extrait:Firestore document get() performance

public void readDoc(final String key) { 
    final long start = System.currentTimeMillis(); 
    docsCollection.document(key).get().addOnCompleteListener(
     new OnCompleteListener<DocumentSnapshot>() { 
     @Override public void onComplete(@NonNull Task<DocumentSnapshot> task) { 
      long end = System.currentTimeMillis(); 
      Log.d("FirestoreStorage", "get() time: " + (end - start)); 
     } 
     }); 
} 

Voici ce que je vois dans LogCat:

10-10 22:30:06.026 D/FirestoreStorage: get() time: 1666 
10-10 22:30:08.199 D/FirestoreStorage: get() time: 264 

La première lecture est toujours très lente lit, à la suite sont sur 200ms. Le document est vraiment petit, actuellement il n'y a que 4 propriétés et seulement un (int) est non nul, donc la taille n'est pas un problème. Exécution de l'application sur un téléphone réel, Nexus 6 sur Android 7.1

Question: qu'est-ce que je fais mal? Je suis fondamentalement en utilisant un échantillon de "Getting data »du Guide pratique.

A lire comme cela devrait prendre 0 millisecondes. S'il n'y a pas de solution, je suppose que je dois renoncer à l'idée de stockage en temps réel comme le seul stockage pour l'application et revenir à SQLite simple et utiliser Firebase/Firestore comme un stockage en nuage séparé.

PS initialisation de stockage de Firestore et les journaux correspondants, désolé de ne pas 500ms mais 350, il est différent, parfois 400, parfois 300:

public FirestoreStorage(String userRef) { 
    Log.i(TAG, "User ref: \"" + userRef + "\""); 
    db = FirebaseFirestore.getInstance(); 
    Log.i(TAG, "Is persistence enabled: " + db.getFirestoreSettings().isPersistenceEnabled()); 
    DocumentReference userDoc = db.collection("users").document(userRef); 
    prefsCollection = userDoc.collection("prefs"); 
    prefsCollection.addSnapshotListener(
     Executors.newFixedThreadPool(2), 
     new EventListener<QuerySnapshot>() { 
      @Override 
      public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) { 
      Log.d(TAG, "Prefs.onEvent"); 
     } 
    }); 
    Log.i(TAG, "Snapshot listener added"); 

    try { 
     Thread.sleep(2000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    } 

Journaux:

10-11 23:11:42.382 I/FirestoreStorage: User ref: "<cut>" 
10-11 23:11:42.474 I/FirestoreStorage: Is persistence enabled: true 
10-11 23:11:42.496 I/FirestoreStorage: Snapshot listener added 
10-11 23:11:42.855 D/FirestoreStorage: Prefs.onEvent 
+0

Comment vous attendez-vous à un appel réseau pour renvoyer les données en 0 millisecondes? –

+0

Je ne sais pas :) Je ne m'attendais pas à ce que le réseau soit impliqué là-bas, je pensais qu'il me renverrait juste la version qu'il a mise en cache localement. Si c'est ce que j'ai quand j'attache un écouteur, pourquoi get() serait différent? C'est très déroutant. Idéalement, je préférerais un drapeau pour dire si je veux essayer et obtenir des données réelles du serveur ou je veux juste des données locales rapides – smok

Répondre

3

Ces get() demandes sont en train de lire les données du back-end-Cloud Firestore, sur le réseau, donc ils vont nécessairement être beaucoup plus lent que SQLite qui est en train de lire localement à partir du disque. La première lecture est également susceptible d'être plus lente que les suivantes car elle doit initier le canal réseau vers le backend. Nous allons chercher à améliorer les performances au fil du temps, mais vous ne pouvez pas vous attendre à 0 ms si vous récupérez des données sur le réseau.

Vous pouvez vouloir enable offline persistence qui permettrait la mise en cache locale des données que vous avez précédemment lues. Notez cependant que les appels get() essaieront quand même de toucher le réseau en premier pour vous fournir des données aussi à jour que possible. Si vous utilisez plutôt addSnapshotListener(), nous vous appellerons immédiatement avec les données mises en cache, sans attendre le réseau.

+0

Merci pour la réponse rapide, Michael. La persistance hors ligne est déjà activée, j'ai vérifié en obtenant les paramètres de base de données. J'ai également essayé d'ajouter l'auditeur et il est appelé, le délai était d'environ 500 ms. Quoi qu'il en soit, c'est un modèle complètement différent, je dois maintenant mettre ces données en cache explicitement jusqu'à ce que j'en aie besoin plus tard, cela complique beaucoup les choses – smok

+0

Si la persistance est activée et que vous utilisez un programme d'écoute snapshot pour lire les données précédemment récupérées, le délai ne devrait pas . Ce serait utile si vous pouviez partager un exemple complet de code. –

+0

Bien sûr, ajouté à la question – smok