简体   繁体   中英

How to ensure that all operations in a cloud function have been successfully completed?

I am using Firebase Cloud Functions, which get triggered by the creation of a document in Firestore. On creation of the object, I need to undertake two different operations in parallel:

  1. update the value of a field in a specific document (not the one which was created and triggered the cloud function)
  2. run a transaction on another document.

So my questions are:

  1. How do I ensure that both of my operations have been successfully completed before ending the cloud function itself ?
  2. How do I implement separate retry mechanism for each of the two operations (as I do not want a common retry mechanism for the whole function as it can redo the transaction operation even if it was the other operation that had failed)?

Here is my current code:

exports.onCityCreated = functions.firestore
    .document('Cities/{cityId}')
    .onCreate((snap, context) => {
        const db = admin.firestore(); 
        const newCity = snap.data();
        const mayorId = newEvent.mayorID;
        const mayorRef = db.doc('Users/'+ mayorId);

        const timestamp = admin.firestore.FieldValue.serverTimestamp();
        db.doc('Utils/lastPost').update({timestamp: timestamp});    //First Operation - Timestamp Update

        return db.runTransaction(t => {    //Second Operation - Transaction
                return t.get(mayorRef).then(snapshot => {
                    var new_budget = snapshot.data().b - 100;
                    return t.update(mayorRef, {b: new_budget});
                })
            .then(result => {
                return console.log('Transaction success!');
            })
            .catch(err => {
                console.log('Transaction failure:', err);
            });
        });
});

Whenever you have multiple operations like this, the solution is to use Promise.all() . This takes an array of promises, and in turn returns a promise that resolves when all promises you passed in are resolved.

exports.onCityCreated = functions.firestore
    .document('Cities/{cityId}')
    .onCreate((snap, context) => {
        const db = admin.firestore(); 
        const newCity = snap.data();
        const mayorId = newEvent.mayorID;
        const mayorRef = db.doc('Users/'+ mayorId);

        const timestamp = admin.firestore.FieldValue.serverTimestamp();
        var p1 = db.doc('Utils/lastPost').update({timestamp: timestamp});

        var p1 = db.runTransaction(t => {
                return t.get(mayorRef).then(snapshot => {
                    var new_budget = snapshot.data().b - 100;
                    return t.update(mayorRef, {b: new_budget});
                })
        });
        return Promise.all([p1, p2]);
});

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