简体   繁体   中英

Firestore how to add to a sub collection

I would like to find a doc in a collection, and add items to a sub collection (which might not exist yet):

projects (collection)
   project (doc)
      cluster (collection) // might not exist
        node1 (doc)  // might not exist
           statTypeA (collection)  // might not exist

I was hoping for something like this:

// Know the doc:
db.ref(`projects/${projectId}/cluster/node1/${statType}`).add()
// Or filter and ref:  
db.collection('projects').where(..).limit(1).ref(`cluster/node1/${statType}`).add()

I ended up solving it like this but it's ugly, verbose and slow as it has to come back with a number of read ops first. Am I doing this right?

const projectRefs = await db.collection('projects')
  .where('licenseKey', '==', licenseKey)
  .limit(1)
  .get();

if (!projectRefs.docs) {
  // handle 404
}

const projectRef = projectRefs.docs[0].ref;

const cluster = await projectRef.collection('cluster')
  .doc('node1').get();

await cluster.ref.collection(statType).add({ something: 'hi' });

Edit:

The way I ended up handling this in a better way is a combination of flattening to other collections and also using arrays for stats. Feels much better:

// projects
{
  projectId1
}

// instances (to-many-relationship) (filter based on projectId)
{
  projectId
  statTypeA: []
  statTypeB: []
}

Your "nasty thing" is much closer to the way things work.

In your first attempt, you're trying to combine a query and a document creation in one operation. The SDK doesn't work like that at all. You are either reading or writing with any given bit of code, never both at once. You should do the query first, find the document, then use that to create more documents.

get() returns a promise that you need to use to wait on the results of the query. The results are not available immediately, as your code is currently assuming.

The documentation shows example code of how to handle the results of an asynchronous query. Since your code uses async/await, you can convert it as needed. Note that you have to iterate the QuerySnapshot obtained from the returned promise to see if a document is found.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM