0

So I've been writing some code to sync my Firestore with another program's database so I've added references.

I want my onCreate method to get a reference number from a seller entry, make a new document with that reference number as well as update orderReference field in the existing document (I want the database to handle it instead of making queries on the client/app), delete the previous order since it's ID can't be updated from functions and update the orderNumber field.

I don't get a new document created nor updated values. I'm really new to Node.js and promises. Any tips and suggestions are welcome.

    exports.createOrderReference = functions.firestore.document('/orders/{order}').onCreate((snapshot, context) => {
    var id = snapshot.id; //id of order document
    var sellerID = snapshot.data().sellerID;

    var orderNumber = 0;
    var content;
    var sellerSnapID;
    return admin.firestore().collection('sellers').where("ID", "==", sellerID).get().then((qSnapshot) => {
        var docs = qSnapshot.docs;
        orderNumber = docs[0].data().orderReferenceNumber;
        sellerSnapID = docs[0].id;
        content = snapshot.data();
        Object.assign(content, {orderReference: orderNumber});
        console.log(content); // <----- last execution
        return content;
    }).then(() => {
        return admin.firestore().collection('orders').doc(orderNumber).set(content).then(() => {
            var promises = [];
            promises.push(admin.firestore().collection('orders').doc(id).delete());
            orderNumber++;
            promises.push(admin.firestore().collection('sellers').doc(sellerSnapID).update({orderReferenceNumber: orderNumber}));
            return Promise.all(promises);
        });
    }).catch((err) => {
        return err;
    });

Updated code

exports.createOrderReference = functions.firestore.document('/orders/{order}').onCreate((snapshot, context) => {
    var id = snapshot.id; //id of order document
    var sellerID = snapshot.data().sellerID;

    var orderNumber = 0;
    var content;
    var sellerSnapID;
    return admin.firestore().collection('sellers').where("ID", "==", sellerID).get().then((qSnapshot) => {
        var docs = qSnapshot.docs;
        orderNumber = docs[0].data().orderReferenceNumber;
        var orderID = docs[0].data().orderReferenceNumber;
        sellerSnapID = docs[0].id;
        content = snapshot.data();
        content.orderReference = orderNumber;

        return admin.firestore().collection('orders').doc(orderID).set(content);
    }).then(() => {
        orderNumber++;
        var promises = [];
        promises.push(admin.firestore().collection('orders').doc(id).delete());
        promises.push(admin.firestore().collection('sellers').doc(sellerSnapID).update({orderReferenceNumber: orderNumber}));
        return Promise.all(promises);
    }).catch((err) => {
        return err;
    });
});

1 Answer 1

1

If you want to chain the promises you need to return a promise within then().

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#Chaining, which explains that:

If the function passed as handler to then returns a Promise, an equivalent Promise will be exposed to the subsequent then in the method chain.

Currently, in your first then you return content, which is not a promise. You should modify your code along the following lines:

exports.createOrderReference = functions.firestore.document('/orders/{order}').onCreate((snapshot, context) => {
var id = snapshot.id; //id of order document
var sellerID = snapshot.data().sellerID;

//....

return admin.firestore().collection('sellers').where("ID", "==", sellerID).get()
.then((qSnapshot) => {
    //.....
    //Set the value of content

    //Return a promise (from the set() method)     
    return admin.firestore().collection('orders').doc(orderNumber).set(content);
})
.then(() => {
    //.....

    //Return a promise, as you do with   
    return Promise.all(promises);

})
.then(results => {
    //.....
    //Return a promise
}).catch((err) => {
    console.log(err)
    return null;
});

You may also watch the official Firebase video series here: https://firebase.google.com/docs/functions/video-series/. In particular watch the three videos titled "Learn JavaScript Promises" (Parts 2 & 3 especially focus on background triggered Cloud Functions, but it really worth watching Part 1 before).

Sign up to request clarification or add additional context in comments.

13 Comments

I modified the code as you recommended, but the end result is still the same, it won't create a new order document as well as execute update and delete actions.
Can you update your question with the new code. Just add it in the question under an "Update" title. I'll review it.
Strange... At first glance it looks like it should work. The only remark I would have is that you may use a transaction since you increment a value read from the DB. What happens if you put console.logs in each then to check the different values? What do you see in the Firebase console Cloud Functions log?
I logged the orderNumber and the content values, both log correct, but for some reason it won't create a document. Function logs return "ok" value each time.
I'll just update fields instead of creating new documents to avoid any additional work. Thank you for your help :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.