0

I'm creating a simple job board site.

You have a JobSeeker, a JobListing and a JobApplication

Both the JobSeeker and the JobListing should have a collection of JobApplications.

When a JobSeeker applies for a job, I want to create a JobApplication document, and add it to both the JobSeeker's collection, and the JobListing's collection.

But that should be a reference to a single document. (ie. if you update it in one place, it should update in the other).

How do I achieve this?

I see according to this answer:

Cloud Firestore multiples document with the same reference

I can add a Reference as a datatype in Firestore - but I'm not exactly sure which method to use to add it.

ie. the collection.add method accepts DocumentData, but I can't see how to set that as a reference?

Can you tell me what syntax to use to:

  1. Create the JobApplication document
  2. Add the document reference to a collection.
  3. Retrieve the document reference from either collection.
dwjohnston
  • 11,163
  • 32
  • 99
  • 194

1 Answers1

0

Here's the way I ended up solving this:

To set the data:


    const docData = {
      listingId: "someExistingId", 
      jobSeekerId: "anotherExistingId", 
      otherData: "whatever other data goes here", 
    }

    const docRef = await db.collection("job-application-collection")
        .add(docData); 
    await db.collection(`job-seeker-collection/${docData.jobSeekerId}/applications`)
        .add({ref:docRef}); 
    await db.collection(`job-listing-collection/${docData.listingId}/applications`)
        .add({ref:docRef}); 

That as, what we do is we create one 'real' document, that goes into the job-application-collection and in the JobSeeker and JobListing collections we add a 'pointer document' that just contains a single field ref, containing the document reference.

To retrieve it (in this example, retrieve all of the applications for a given JobSeeker):

  const jobSeekerId = "someJobSeekerId"; 
  const colRef = await db.collection(`job-seeker-collection/$jobSeekerId}/applications`);
  const colSnapshot = await colRef.get();  

  /**
   * The docs on the collection are actually just documents containing a reference to the actual JobApplication document. 
   */
  const docsProms = colSnapshot.docs.map((async (colDocData) => {
    const snapshot =  await colDocData.data().ref.get(); 
    return {
      ...snapshot.data(), 
      id: snapshot.id, 
    }
   })); 

  const data = await Promise.all(docsProms); 

  return data; 

Pretty straight forward, we get the collection on the JobSeeker document, and then on each of those documents, there is a ref field, which we can use the .get() method to return a document snapshot.

dwjohnston
  • 11,163
  • 32
  • 99
  • 194