title: Firestore document get() performance
body: <p>Just starting to explore Firestore storage and first thing to do - read a simple small document in my Android app by document key (authenticated with Google, but probably that's not important). Here is a snippet:</p>
  
  <pre><code>public void readDoc(final String key) {
    final long start = System.currentTimeMillis();
    docsCollection.document(key).get().addOnCompleteListener(
        new OnCompleteListener&lt;DocumentSnapshot&gt;() {
          @Override public void onComplete(@NonNull Task&lt;DocumentSnapshot&gt; task) {
            long end = System.currentTimeMillis();
            Log.d("FirestoreStorage", "get() time: " + (end - start));
          }
        });
  }
  </code></pre>
  
  <p>Here is what I see in LogCat:</p>
  
  <pre><code>10-10 22:30:06.026 D/FirestoreStorage: get() time: 1666
  10-10 22:30:08.199 D/FirestoreStorage: get() time: 264
  </code></pre>
  
  <p>The first read is always very slow, subsequent reads are about 200ms. The document is really small, currently it's just 4 properties and only one (int) is non-null, so the size is not an issue. Running the app on a real phone, Nexus 6 on Android 7.1</p>
  
  <p>Question: what am I doing wrong? I'm basically using a sample from <a href="https://cloud.google.com/firestore/docs/query-data/get-data" rel="nofollow noreferrer">"Getting data</a>" of the How-to Guide.</p>
  
  <p>A read like this should take <strong>0 milliseconds</strong>. If there's no workaround, I guess I have to give up the idea of Realtime storage as the only storage for the app and get back to plain SQLite and use Firebase/Firestore as a separate cloud storage.</p>
  
  <p><strong>UPDATE</strong> Starting from version 16.0.0 <a href="https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/DocumentReference#get()" rel="nofollow noreferrer">DocumentReference.get()</a> and <a href="https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/Query#get()" rel="nofollow noreferrer">Query.get()</a> have a new parameter "source" that allows to control where the data is read from - only server, only cache or try server then cache.</p>
  
  <p><strong>PS</strong> Firestore storage initialization and corresponding logs, sorry not 500ms but 350, it's different, sometimes 400, sometimes 300:</p>
  
  <pre><code>  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&lt;QuerySnapshot&gt;() {
            @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();
      }
    }
  </code></pre>
  
  <p>Logs:</p>
  
  <pre><code>10-11 23:11:42.382 I/FirestoreStorage: User ref: "&lt;cut&gt;"
  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
  </code></pre>