128

This works:

db.collection('users').doc('id').get()
  .then((docSnapshot) => {
    if (docSnapshot.exists) {
      db.collection('users').doc('id')
        .onSnapshot((doc) => {
          // do stuff with the data
        });
    }
  });

... but it seems verbose. I tried doc.exists, but that didn't work. I just want to check if the document exists, before subscribing to realtime updates on it. That initial get seems like a wasted call to the db.

Is there a better way?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Stewart Ellis
  • 1,281
  • 2
  • 8
  • 4

5 Answers5

203

Your initial approach is right, but it may be less verbose to assign the document reference to a variable like so:

const usersRef = db.collection('users').doc('id')

usersRef.get()
  .then((docSnapshot) => {
    if (docSnapshot.exists) {
      usersRef.onSnapshot((doc) => {
        // do stuff with the data
      });
    } else {
      usersRef.set({...}) // create the document
    }
});

Reference: Get a document

Excellence Ilesanmi
  • 3,295
  • 1
  • 18
  • 17
  • It appears that the code has undergone a change in structure, transitioning from evaluating a boolean property to invoking a function Previously: ```if (docSnapshot.exists)``` It should now be: ```if (docSnapshot.exists())``` – doomsday Aug 31 '23 at 11:20
17

Please check following code. It may help you.

 const userDocRef = FirebaseFirestore.instance.collection('collection_name').doc('doc_id');
   const doc = await userDocRef.get();
   if (!doc.exists) {
     console.log('No such document exista!');
   } else {
     console.log('Document data:', doc.data());
   }
sh_ark
  • 557
  • 5
  • 14
Dwipal Parmar
  • 244
  • 2
  • 8
3

I know its late, but it's actually snapshot.empty not snapshot.exists . snapshot.empty checks if a doc exists and returns accordingly. happy coding

dealdrey
  • 39
  • 2
  • 1
    Both `exists` and `empty` are valid depending on the snapshot type. Query snapshots - such that return a list of snapshots have `querySnapshot.empty` as in "a list is empty". Document snapshot is for a single document and they have `documentSnapshot.exists` field as in "a document exists" – kidroca Apr 12 '22 at 11:34
3

Please note that in Firebase v9 (Modular SDK) exists is a method, not a property (which would give you falsy results all the time), as per the docs.

Eduard
  • 3,395
  • 8
  • 37
  • 62
  • 1
    There's nothing inherently wrong with a returned `false` value. The documentation explains that if there is no document, it'll return false. The goal would therefore be to make code that is idempotent and would work with the guiding principles of firestore The documentation explains: `Note: If there is no document at the location referenced by docRef, the resulting document will be empty and calling exists on it will return false.` I recommend using the methods that the devs have created – New-Way Mar 27 '22 at 03:55
  • 1
    @New-Way not really sure what you’re trying to say, to be honest. I simply mentioned in v9 exists is a method, not a property anymore, so be aware. – Eduard Mar 28 '22 at 07:45
1

In case you are using PHP-Firestore integration, like me, write something like this:

$firestore = new FirestoreClient();
$document = $firestore->document('users/john');
$snapshot = $document->snapshot();

if ($snapshot->exists()) {
   echo "John is there!";
}

Enjoy! o/

Nowdeen
  • 1,401
  • 14
  • 20