Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cloud Functions using wildcard path don't work

I try to update all documents in a collection with a Cloud Function. With this code it worked for updating one document (with the id 0) in the collection releasedQuestions:

exports.decreaseQuestionRestDuration = functions.https.onRequest((request, response) => {
   const test = admin.firestore().doc('releasedQuestions/0').update({restDuration: 42})
        .then(snapshot => {
            response.send(0)
        })
        .catch(error => {
            console.log(error)
            response.status(500).send(error)
        })
});

but when i will update all documents in the collection with a wildcard path like this:

const test = admin.firestore().doc('releasedQuestions/{qid}').update({restDuration: 42})

it doesn't work. Can anyone help me?

My Cloud Firestore structure is this: Cloud Firestore structure

like image 866
Marcel Avatar asked Oct 27 '25 06:10

Marcel


1 Answers

The wildcard path syntax you are using (i.e. doc('releasedQuestions/{qid}')) can only be used in Cloud Functions definition, when, for example, you define a Cloud Firestore trigger by specifying a document path and an event type, as follows:

exports.useWildcard = functions.firestore
    .document('users/{userId}')
    .onWrite((change, context) => {...});

In your case you are actually calling the doc() method, for which the documentPath parameter shall be a string. This is why it works in the first case but not in the second one (there isn't any Firestore document with ID {qid} in your collection).


If you want, in your HTTP Cloud Function, to update all the docs of a collection, you could use a batched write, as follows:

exports.decreaseQuestionRestDuration = functions.https.onRequest((request, response) => {

    const db = admin.firestore();

    db.collection('releasedQuestions').get()
        .then(snapshot => {
            let batch = db.batch();
            snapshot.forEach(doc => {
                batch.update(doc.ref, { restDuration: 42 });
            });
            return batch.commit()
        })
        .then(() => {
            response.send(0)
        })
        .catch(error => {
            console.log(error)
            response.status(500).send(error)
        })

});

Note however, that a batched write can contain up to 500 operations. Therefore, if your collection contains more than 500 documents, you may use Promise.all() instead.


As a side note, it's worth noting the existence of Template literals.

Template literals are enclosed by the backtick (grave accent) character instead of double or single quotes... and can contain placeholders.

like image 114
Renaud Tarnec Avatar answered Oct 28 '25 20:10

Renaud Tarnec