5

Take a look at this code example from the Firestore documentation:

DocumentReference docRef = db.collection("cities").document("SF");
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
        if (task.isSuccessful()) {
            DocumentSnapshot document = task.getResult();
            if (document != null && document.exists()) {
                Log.d(TAG, "DocumentSnapshot data: " + document.getData());
            } else {
                Log.d(TAG, "No such document");
            }
        } else {
           Log.d(TAG, "get failed with ", task.getException());
        }
    }
});

https://firebase.google.com/docs/firestore/query-data/get-data

Why check if document != null? If I read the source code correctly (beginner), the exists method checks for nullity internally.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Florian Walther
  • 6,237
  • 5
  • 46
  • 104

4 Answers4

17

A successfully completed task will never pass null for the DocumentSnapshot. If the requested document does not exist, you'll get an empty snapshot. This means that:

  • Calling document.exists() returns false
  • Calling document.getData() throws an exception

So there is indeed no reason to check if document != null before calling document.exists().

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • 3
    Thank you. Good to see that my conclusions were right, because I am a beginner. – Florian Walther Apr 07 '18 at 20:20
  • 1
    And what about the `onEvent` method in the `EventListener`? If I check for an exception and no exception was thrown, is the `DocumentSnapshot` there always NOT null as well? https://firebase.google.com/docs/firestore/query-data/listen – Florian Walther Apr 08 '18 at 09:40
  • *Googler here*. I wrote the code snippet in question and you're right, the `null` check is not needed. I guess I was just feeling extra careful that day. I will fix it! – Sam Stern Apr 11 '18 at 20:22
3

If you execute the following statement:

document != null

It will be evaluated to false, which means that your task is null and the following message will be printed out:

Log.d(TAG, "No such document");

However, if you are calling a method on your task object, (e.g. toString()) it will throw the following error:

java.lang.IllegalStateException: This document doesn't exist. Use DocumentSnapshot.exists() to check whether the document exists before accessing its fields.

This message explicitly tells you to use exists() method rather than to check for nullity.

The official documentation regarding the use of how to get a document method says:

Note: If there is no document at the location referenced by docRef, the resulting document will be null.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
3

if documentSnapshot is nullable you should do the following:

if (documentSnapshot != null) {
    if (documentSnapshot.exists()) {
         //exists
    } else {
         //doesn't exist
    }
} 
AmirReza-Farahlagha
  • 1,204
  • 14
  • 26
  • This works but you dont need multiple if statements. Remove the first statement and replace with this line ``` assert documentSnapshot != null; ``` – Zephania Mwando Nov 12 '20 at 21:02
  • @esmail What if we want to check if the certain field of the requested document exists or not? I get a bad state exception If I try to get the field of the document if it doesn't exist. Below is the question, kindly give it a minute https://stackoverflow.com/questions/68937605/bad-state-cannot-get-a-field-on-a-documentsnapshotplatform-which-does-not-exist – Faizan Kamal Aug 26 '21 at 11:36
0

Another straightforward fix for such errors would be


DocumentSnapshot documentSnapshot = task.getResult();

 assert documentSnapshot != null;
 if (documentSnapshot.exists()) {

      //Your operation e.g
     ArrayList<String> obj= (ArrayList<String>) documentSnapshot.get("documentObject");
     String s = Objects.requireNonNull(obj).toString();
     Toast.makeText(context, "THIS WORKS "+ s, Toast.LENGTH_SHORT).show();

  } else {
     //Another operation
   Toast.makeText(context, "DOES NOT EXIST", Toast.LENGTH_SHORT).show();
  }
Zephania Mwando
  • 118
  • 1
  • 9