Firebase的云功能 - 序列化返回值时出错:

时间:2017-06-27 21:47:23

标签: javascript node.js firebase firebase-realtime-database google-cloud-functions

我有一个云函数,用于交叉引用两个列表,并查找列表中彼此匹配的值。该函数似乎工作正常,但在日志中我一直看到这个Error serializing return value: TypeError: Converting circular structure to JSON。这是函数......

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

    });

});

我尝试将return放在completionRef.set(matchedContacts);前面,但这仍然给我错误。不确定我做错了什么以及如何消除错误。谢谢你的帮助

4 个答案:

答案 0 :(得分:11)

在返回Firebase数据库上的多个Promise时,我遇到了完全相同的问题。起初我打电话来说:

return Promise.all(promises);

我的promises对象是我正在使用的数组,我通过调用promises.push(<add job here>)推送所有需要执行的作业。我想这是执行作业的有效方法,因为现在作业将并行运行。

云功能有效,但我得到了你描述的完全相同的错误。

但是,正如Michael Bleigh在评论中提出的那样,添加then修复了问题,我不再看到错误:

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

如果这不能解决您的问题,可能需要将循环对象转换为JSON格式。这里写的是一个例子,但我没有尝试过:https://stackoverflow.com/a/42950571/658323(它使用了圆形-json库)。

2017年12月更新:在最新的Cloud Functions版本中,云计算功能会出现返回值(Promise或值),因此return;会导致以下错误:Function returned undefined, expected Promise or value虽然该函数将被执行。因此,当您没有返回承诺并希望云功能完成时,您可以返回一个随机值,例如return true;

答案 1 :(得分:0)

尝试:

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);
});

答案 2 :(得分:0)

我有一个非常相似的设置相同的错误输出,无法弄清楚如何摆脱这个错误。 我不完全确定以前的答案是否已经捕获了所有的本质,所以我给你留下了解决方案,也许它对你有帮助。

最初我的代码看起来像这样:

return emergencyNotificationInformation.once('value', (data) => {
    ...
    return;
});

但是在添加之后,抓住错误确实消失了。

return emergencyNotificationInformation.once('value')
    .then((data) => {
        ...
        return;
    })
    .catch((error) => {
        ...
        return:
    });
}

答案 3 :(得分:0)

我们通过在链的底部返回Promise.resolve()来修复具有相同错误的类似问题,例如:

return event.data.ref.parent.child('subject').once('value')
    .then(snapshot => {
        console.log(snapshot.val());
        Promise.resolve();
    }).catch(error => {
        console.error(error.toString());
    });