Florian Walther
Florian Walther

Reputation: 6971

Firestore - Difference between DocumentSnapshot and QueryDocumentSnapshot

The documentation says

A QueryDocumentSnapshot contains data read from a document in your Firestore database as part of a query. The document is guaranteed to exist and its data can be extracted using the getData() or get() methods.

QueryDocumentSnapshot offers the same API surface as DocumentSnapshot. Since query results contain only existing documents, the exists() method will always return true and getData() will never be null.

https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/QueryDocumentSnapshot

But it doesn't explain when I should use one over the other. I tried both in a SnapshotListener on a Collection and both worked.

protected void onStart() {
    super.onStart();
    notebookRef.addSnapshotListener(new EventListener<QuerySnapshot>() {
        @Override
        public void onEvent(QuerySnapshot queryDocumentSnapshots, FirebaseFirestoreException e) {
            if (e != null) {
                Toast.makeText(MainActivity.this, "Error while loading!", Toast.LENGTH_SHORT).show();
                Log.d(TAG, e.toString());
                return;
            }

            String allNotes = "";

            for (QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots) {


                Note note = documentSnapshot.toObject(Note.class);

                String title = note.getTitle();
                String description = note.getDescription();

                allNotes += "\nTitle: " + title + " Description: " + description;

            }

            textViewData.setText(allNotes);
        }
    });
}

Upvotes: 24

Views: 19865

Answers (2)

Pranjal Choladhara
Pranjal Choladhara

Reputation: 913

  1. Use DocumentSnapshot when you are getting single collection using your id.

  2. When you query your database for multiple documents/rows you get a QuerySnapshot. It is a like a Resultset returned by the jdbc. You have to iterate through the snapshot and convert to your own object, here use QueryDocumentSnapshot.

    for(QueryDocumentSnapshot doc : snapshots){
      Note note = doc.toObject(Note.class);
    }
    

Upvotes: -1

Doug Stevenson
Doug Stevenson

Reputation: 317958

As you've stated:

QueryDocumentSnapshot offers the same API surface as DocumentSnapshot

This is because QueryDocumentSnapshot is a subclass of DocumentSnapshot. This means that every QueryDocumentSnapshot can be assigned (downcast) to a variable of type DocumentSnapshot. They do exactly the same thing, except for the difference between them that you've stated:

Since query results contain only existing documents, the exists() method will always return true and getData() will never be null.

So, if you're dealing with a QueryDocumentSnapshot, you have a guarantee about what the exists() method will return. If you're dealing with a DocumenSnapshot (that is not actually a QueryDocumentSnapshot that's been downcast), you don't have this guarantee.

I think you might just be putting too much weight on the fact that one is a subclass of the other. Just use the one that you see in the API docs and don't cast anything to other types, unless you really know you need to do so.

Upvotes: 30

Related Questions