Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to efficiently add items to collection with firebase firestore

I have an array of tags that I would like to add to a firestore collection.

If I'm not misunderstanding the approach I have here, I think I'm making individual adds to the collection when I think it would be more efficient to 'group' them and set them all at once. Is something like this possible? Also would it be possible to add the document to the workouts collection at the same time?

Right now I'm looking at tags.length + 1 writes to firebase for every call to this function. I'd like to reduce that as much as possible.

logWorkoutAsync({ userId, timeStamp, tags }){
    var db = this.firebase.firestore();

    return db.collection('users').doc(userId).collection('workouts').add({
        timeStamp,
        'class': false
    }).then(doc => {

        var tagsCollection = doc.collection('tags')

        var promises = []

        tags.forEach(t => {
            promises.push(tagsCollection.doc(t.id.toString()).set(t))
        })

        return Promise.all(promises)
    })
}
like image 873
RoboKozo Avatar asked Oct 17 '17 17:10

RoboKozo


People also ask

How many documents can be in a collection Firebase?

10 for single-document requests and query requests. 20 for multi-document reads, transactions, and batched writes. The previous limit of 10 also applies to each operation.

Does firestore automatically create collections?

Collections and documents are created implicitly in Cloud Firestore. Simply assign data to a document within a collection. If either the collection or document does not exist, Cloud Firestore creates it.


2 Answers

Cloud Firestore has support for batched writes, see the docs here: https://firebase.google.com/docs/firestore/manage-data/transactions

So you could do something like this:

logWorkoutAsync({ userId, timeStamp, tags }){
    var db = this.firebase.firestore();

    return db.collection('users').doc(userId).collection('workouts').add({
        timeStamp,
        'class': false
    }).then(doc => {

        var tagsCollection = doc.collection('tags');

        // Begin a new batch
        var batch = db.batch();

        // Set each document, as part of the batch
        tags.forEach(t => {
            var ref = tagsCollection.doc(t.id.toString());
            batch.set(ref, t);
        })

        // Commit the entire batch
        return batch.commit();
    })
}
like image 117
Sam Stern Avatar answered Oct 26 '22 12:10

Sam Stern


IF you want to add multiple documents to collection you could do something like this which worked fine for me since I was stuck in a similar case.

let colRef = db.collection('cars')

/// Batch Thing //
var batch = db.batch();

let cars = [{name: 'Audi', model: 'A8'}, {name: 'BMW', model: '730'}]
cars.forEach(c => {
  let ref = colRef.doc(`${c.name}`)
  batch.set(ref, {
    name: `${c.name}`,
    model: `${c.model}`
  })
})

return batch.commit()
  .then(data => {
    console.log('good')
  })
  .catch(error => {
    console.log('there is an error')
  })
like image 35
Marketingexpert Avatar answered Oct 26 '22 11:10

Marketingexpert