52

I have a collection called 'categories' containing a single document with ID: 5gF5FqRPvdroRF8isOwd.

I have another collection called 'tickets'. Each ticket has a reference field which assigns the ticket to a particular category.

The field in the tickets collection is called 'category' and has a field type of reference.

In the code below, categoryDocId is the document ID of the category I want to query by.

const categoryDocID = `5gF5FqRPvdroRF8isOwd`;

const files = await firebase
  .firestore()
  .collection('tickets')
  .where('category', '==', categoryDocID)
  .get();

Why does files.length return 0?

For testing, I changed the category field type to string, and set it to the category ID instead of a direct reference. This correctly returned tickets assigned to the category, which leads me to believe it's something about how I'm querying a reference field.

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
jskidd3
  • 4,609
  • 15
  • 63
  • 127
  • This answer seems to indicate that such a query is possible: https://stackoverflow.com/questions/47937202/query-a-reference-field-in-firestore-document. I don't see how your code is different, so it should work the same as there. – Frank van Puffelen Nov 04 '18 at 13:30

3 Answers3

121

As you will read here in the doc, the Reference Data Type is used to store DocumentReferences.

If you want to use it in a query, you cannot use a simple string, neither the UID of the document (i.e. '5gF5FqRPvdroRF8isOwd'), nor the string value that is stored in the field (i.e. '/categories/5gF5FqRPvdroRF8isOwd').

You have to build a DocumentReference and use it in your query, as follows:

JS SDK V9

import { doc, query, collection, where, getDocs } from "firebase/firestore";

const categoryDocRef = doc(db, "categories", "5gF5FqRPvdroRF8isOwd");

const q = query(
  collection(db, "tickets"),
  where("category", "==", categoryDocRef)
);

const files = await getDocs(q);   // !! files is a QuerySnapshot

JS SDK V8

const categoryDocRef = firebase.firestore()
   .collection('categories')
   .doc('5gF5FqRPvdroRF8isOwd');

const files = await firebase   // !! files is a QuerySnapshot
  .firestore()
  .collection('tickets')
  .where('category', '==', categoryDocRef)
  .get();
Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
  • 5
    Thanks for answering Renaud. I just confirmed this in a jsbin: https://jsbin.com/qowelew/4/edit?js,console. I'm not sure why [this accepted answer](https://stackoverflow.com/47937202) is using strings for references. – Frank van Puffelen Nov 04 '18 at 13:47
  • @FrankvanPuffelen Thanks for the confirmation, Frank – Renaud Tarnec Nov 04 '18 at 14:01
  • 12
    At the moment, using `reference` as type is almost useless. Only thing it adds to you is that you don't make mistakes like referencing a document that doesn't exist. They have talked about this on their Google Channel: https://www.youtube.com/watch?v=Elg2zDVIcLo – buryo Feb 23 '20 at 21:09
  • Hi , any suggestions on how to query on the map field? I've my collection document structure like this https://ibb.co/wKvSmFb – Nagesh Sep 19 '20 at 10:04
  • Any update on this? Would just make sense to be able to query by reference id. – ChrisDelClea May 12 '21 at 19:22
  • @ChrisChross AFAIK nothing has changed since the answer was written. – Renaud Tarnec May 13 '21 at 09:05
  • this means that it's not possible to use the firestore UI to query the document by a reference-type field, am I right? – Prusdrum Jul 06 '21 at 07:43
  • You can use the reference type to get a document from a collection. See my answer. – Quins Jul 12 '21 at 23:58
7

With Firebase Version 9 (Dec, 2021 Update):

You must make a document reference with "categories/5gF5FqRPvdroRF8isOwdand" then use it in your query:

import { doc, query, collection, where, getDocs } from "firebase/firestore";

const categoryDocRef = doc(db, "5gF5FqRPvdroRF8isOwd");

const q = query(
  collection(db, "tickets"),
  where("category", "==", categoryDocRef)
);

const ticketDocsSnap = await getDocs(q);
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
  • 3
    This was helpful for me. Thank you. Believe you need to specify from which collection you intend to search for the ref: `const categoryDocRef = doc(db, '', ...)`. – cheshireoctopus Dec 26 '21 at 17:50
1

Here is how I use reference type to query a collection (node.js + typescript):

let myCollectionADocument = await admin.firestore().collection("collection_a").doc("documentId").get();
let myCollectionB = await admin.firestore().collection("collection_b").where("collection_a_id", "==", myCollectionADocument.ref).get();
Dharman
  • 30,962
  • 25
  • 85
  • 135
Quins
  • 785
  • 7
  • 16
  • Please answer my queries in https://stackoverflow.com/questions/68442405/how-to-set-where-condition-on-array-of-reference-selection-in-flutter-using-clou. thanks in advance – Sakthi Karthik Jul 22 '21 at 10:30