0
votes

The console shows that the function has been executed in 2 - 3 seconds. But it takes around 5 minutes to update in database. Is it normal for cloud functions to take so long to propagate changes? Is there any way the delay can be reduced to a few seconds?

Below is the code for cloud function. I trigger it with a url visit. (I know the code smells, but this is a prototype only).

    const listID = req.query.id;
    const user = req.query.user;
    const code = req.query.code;
    const title = req.query.title;
    const desc = req.query.desc;

    var docRef = admin.firestore().collection('users/' + user.toString() + '/wordLists/' + listID.toString() + '/words');
    var docRef2 = admin.firestore().doc("users/" + user.toString() + "/wordLists/" + listID.toString());
    var docRef3 = admin.firestore().doc("users/" + user.toString());    //new 

    var description, length, name, courseId;
    
    description = desc;
    name = title;
    console.log("Description: " + description + ", d: " + desc);

    docRef2.get().then(
        function(doc) {
            if (doc.exists) {
                length = doc.data().length;
                courseId = user.toString()+","+listID.toString()+"," + code.toString();
                admin.firestore().collection('courses').doc(courseId).set({
                    description: description,
                    id: courseId,
                    length: length,
                    name: name,
                    creator: user,
                    downloads: 0,
                    rating: 0,
                    published: true,
                });
                
            } else {
                console.log("FAILED users/" + user.toString() + "/wordLists/" + listID.toString());
            }
            return "Done";
    }).catch(function(error) {
        console.log("Error getting document:", error);
    });

    docRef.get().then(function(querySnapshot){
        querySnapshot.forEach(function(doc) {
        if (doc.exists) {
            var mid = doc.data().meaningID;
            var smi = doc.data().subMeaningIndex;
            var docId = mid.toString() + "," + smi.toString();

            
            admin.firestore().collection('courses/'+ courseId + '/words').doc(docId).set({
                examples: doc.data().examples,
                meaningID: mid,
                subMeaning: doc.data().subMeaning,
                subMeaningIndex: smi,
                word: doc.data().word,
            });
        } else {
            console.log('users/' + user.toString() + '/wordLists/' + listID.toString() + '/words');
        }
        //return "Done";
    });
    return "Done2";
    }).catch(function(error) {
        console.log("Error getting document:", error);
    });
    
    docRef3.get().then(
        function(doc) {
            if (doc.exists) {
                var l = doc.data().coursesCreated;
                l.push(courseId);
                docRef3.update({coursesCreated: l});
            } else {
                console.log("users/" + user.toString() + "/wordLists/" + listID.toString());
            }
            return "Done";
    }).catch(function(error) {
        console.log("Error getting document:", error);
    });
    
    res.send("Success");

Here is the console output. You can see that the console.log output from 4:26 comes after they say the function execution finished. : Console output log

1
You're not dealing with promises correctly. Calling then and catch on each one isn't sufficient. You need to make sure that res.send is only executed after each promise resolves. Simply putting it at the bottom isn't enough - the promises must be chained. - Doug Stevenson

1 Answers

1
votes

In your code, since you execute Promise-based non-blocking functions, the res.send() part is immediately accessed. As Doug writes, you should put it inside a Promise callback.

You should either send a res.send() within a .then() block or a res.status(500).send() within a .catch()block and only once.

You could also use async/await (within a try/catch structure) if you don't want to deal with Promises cascading.