Firebase query by document id PLUS property value

I am completely new to Firebase, maybe I just cannot search for the right keywords, but here’s what I’d like to do:

I would like to read a document from the database by id, but only if that document has a specific property set. To be more specific, this would be something like a tiny blog server, where I want to read a post’s data, but only if its “published” property is set to true. I don’t want unpublished posts to end up on the client side.

I am using the JavaScript SDK, but can only find examples of lookup by either ID or properties…

Is this even possible?


UPDATE: What I have now is (this is Firestore):

firebase.firestore().collection('blog-posts').doc(id).get()

and then later check for the property on the client side:

if (data && data.published === "true")

I would like all the filtering to happen on the server side.

Answer

If you want to get a document only if a field has a certain value, you won’t be able to use get() on its DocumentReference. You will have to perform a query on the collection using both the document ID and field as filters on that query like this, using FieldPath.documentId():

const qsnap = await firebase.firestore()
    .collection('blog-posts')
    .where(firebase.firestore.FieldPath.documentId(), "==", id)
    .where("published", "==" true)
    .get()

This yields a QuerySnapshot, which you will have to check if the document was provided.

if (qsnap.docs.length > 0) {
    const doc = qsnap.docs[0];
}

Note that it still costs 1 document read to perform this query even if the document isn’t returned.