Payload and JS plain object

Hi,

I'm creating a flow to store form data into a Firestore DB with node-red-contrib-cloud-firestore.

On input, the payload contains a object with nested object but when Firestore check it, it fails the test on Object.getPrototypeOf(input) === Object.prototype.

Is something done to the payload when sending it to nodes that could change such a behaviour?

Thank you for your help

2 Likes

Are you using a Function node to create the object you pass to the firestore node? If so, it will likely fail that test due to the internal workings of the Function node. I won't bore you with the details unless you really want to know.

One workaround is to create the object in a Change node instead. If you really need the Function node, then create the object in a Change node and then pass that to the Function node to populate its values. I think that would work.

Another workaround would be to pass the output of your Function node through two JSON nodes - one to encode it to a string and then one to parse it back to an Object. That new object should pass the test being done by the firestore node.

Are you saying an object created in a Function (you're right, that's my case) won't be a plain object? If it's not too much to ask I'm interested in the details :slight_smile:

For the record, here's my Function with the incriminated object:

const allowedKeys = ['firstname', 'name', 'email'];
const contact = {name: null, company: null, mail: null};
msg.payload = msg.payload.form_response.answers.reduce((memo, ans) => {
    const [key, subkey] = ans.field.ref.split('_');
    const value = ans[ans.type];
    switch(true) {
        case key === 'contact':
            contact[subkey] = value;
            break;
        case key === 'firstname':
            memo.push({[key]: value, contact});
            break;
        case allowedKeys.includes(key): 
            memo[memo.length - 1][key] = value;
            break;
        default: console.debug(`${key} key not allowed`);
    }
    return memo;
}, []);
return msg;

If a Change would set msg.contact to a new empty object and pass it to the Function, would that work?

Thanks a lot!

EDIT: The Change workaround works! That's good to have but I'm still interested in the why :wink:

The Function node uses the node vm module to run its code in a sandbox. That sandbox gets its own instances of all the primitive types, like Object.

The strict equality test used by the firestore node is checking whether the prototype of your object is exactly the same object in memory as the prototype of Object.

As the Function node has its own copy of Object, then whilst they are identical things, they are not exactly the same instance in memory so the test fails.

2 Likes

Thank you, that's much clearer now! I'll keep that in mind for my future development !