Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cloud Functions for Firebase - Error serializing return value:

I have a Cloud Function used to cross reference two lists and find values that match each other across the lists. The function seems to be working properly, however in the logs I keep seeing this Error serializing return value: TypeError: Converting circular structure to JSON . Here is the function...

exports.crossReferenceContacts = functions.database.ref('/cross-ref-contacts/{userId}').onWrite(event => {

    if (event.data.previous.exists()) {
        return null;
    }

    const userContacts = event.data.val();
    const completionRef = event.data.adminRef.root.child('completed-cross-ref').child(userId);
    const removalRef = event.data.ref;

    var contactsVerifiedOnDatabase ={};
    var matchedContacts= {};


    var verifiedNumsRef = event.data.adminRef.root.child('verified-phone-numbers');
    return verifiedNumsRef.once('value', function(snapshot) {

        contactsVerifiedOnDatabase = snapshot.val();

        for (key in userContacts) {
            //checks if a value for this key exists in `contactsVerifiedOnDatabase`
            //if key dioes exist then add the key:value pair to matchedContacts
        };

        removalRef.set(null); //remove the data at the node that triggered this onWrite function
        completionRef.set(matchedContacts); //write the new data to the completion-node

    });

});

I tried putting return in front of completionRef.set(matchedContacts); but that still gives me the error. Not sure what I am doing wrong and how to rid the error. Thanks for your help

like image 532
MikeG Avatar asked Jun 27 '17 21:06

MikeG


2 Answers

I was having the exact same issue when returning multiple promises that were transactions on the Firebase database. At first I was calling:

return Promise.all(promises);

My promises object is an array that I'm using where I'm pushing all jobs that need to be executed by calling promises.push(<add job here>). I guess that this is an effective way of executing the jobs since now the jobs will run in parallel.

The cloud function worked but I was getting the exact same error you describe.

But, as Michael Bleigh suggested on his comment, adding then fixed the issue and I am no longer seeing that error:

return Promise.all(promises).then(() => {
  return true;
}).catch(er => {
  console.error('...', er);
});

If that doesn't fix your issue, maybe you need to convert your circular object to a JSON format. An example is written here, but I haven't tried that: https://stackoverflow.com/a/42950571/658323 (it's using the circular-json library).

UPDATE December 2017: It appears that in the newest Cloud Functions version, a cloud function will expect a return value (either a Promise or a value), so return; will cause the following error: Function returned undefined, expected Promise or value although the function will be executed. Therefore when you don't return a promise and you want the cloud function to finish, you can return a random value, e.g. return true;

like image 199
steliosf Avatar answered Nov 05 '22 10:11

steliosf


Try:

return verifiedNumsRef.once('value').then(function(snapshot) {
    contactsVerifiedOnDatabase = snapshot.val();

    for (key in userContacts) {
        //checks if a value for this key exists in `contactsVerifiedOnDatabase`
        //if key dioes exist then add the key:value pair to matchedContacts
    };

    return Promise.all([
      removalRef.set(null), //remove the data at the node that triggered this onWrite function
      completionRef.set(matchedContacts)
    ]).then(_ => true);
});
like image 39
Michael Bleigh Avatar answered Nov 05 '22 12:11

Michael Bleigh