【问题标题】:How to fix "Function returned undefined, expected Promise or value" error when function loops如何在函数循环时修复“函数返回未定义、预期的 Promise 或值”错误
【发布时间】:2020-03-09 08:39:56
【问题描述】:

我有一个我开发的安卓应用程序,它允许用户注册。我写了一个firebase云函数,在创建用户时触发,为刚刚注册的用户生成一个5位随机整数值,并将生成的代码存储在firebase实时数据库中,结构如下。

MainProject
     |
     |-Codes
         |-UniqueUID_1
                |-code:72834
         |-UniqueUID_2
                |-code:23784

我为确保代码生成在后端而部署的功能如下所示。有一个值“checker”被初始化为 0。我使用这个值来确定何时退出 while 循环。基本上我希望该函数生成一个 5 位数的随机值,然后检查实时数据库是否该生成的值存在于“代码”下的所有条目中,如果它不存在,则将其附加到相关 UID 下的代码中。如果存在,checker 保持为零,循环继续。

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

var checker = 0;
exports.createUserCode = functions.auth.user().onCreate(event => {

    while (checker == 0){
        var newRand = getUserCode(89999,10000);
        var userObject = {
            uCode : newRand
        };
        //run a db query to strategically check value generated
        return admin.database().ref("Codes/").orderByChild("uCode").equalTo(newRand).once("value",snapshot => {
            if (!snapshot.exists()){
                checker = 1;
                //add uCode into respective uid slot under Codes
                console.log(""+newRand+" : "+event.uid);
                return admin.database().ref('Codes/' + event.uid).set(userObject);

            }else{
                checker = 0;
                console.log("uCode "+newRand+" exists");
                console.log("uCode generation failed for: "+event.uid);
            }
        });
    }
});

function getUserCode(size, add){
    return Math.floor(Math.random()*size+add);
}

我测试了它,它运行良好。我以为问题解决了。然而,在第 7 到第 11 次试验中,它给了我一个 Function returned undefined, expected Promise or value 错误。过了一会儿我又试了一次,它生成的代码很好。其他人对其进行了测试,并带来了同样的错误。

如何解决此问题以确保它始终有效?提前致谢。

【问题讨论】:

  • 我最好的猜测是 else 分支中缺少 return 语句,以防快照存在
  • @Michiel 我会测试一下,看看会发生什么。我担心循环是问题的原因,我认为当有多个调用时全局变量没有任何影响

标签: javascript firebase firebase-realtime-database firebase-authentication google-cloud-functions


【解决方案1】:

我真的不清楚这个函数应该做什么,顶级 while 循环对我来说没有意义。但是,我可以看到这段代码的操作存在一些问题。

首先,它过于依赖全局状态checker。对于所有函数调用,该值不会是一致的,因为它们都不会在同一个服务器实例上运行。每个正在运行的服务器实例都将看到不同的 checker 值。请watch this video series了解有关 Cloud Functions 如何运行代码的更多信息。

其次,当函数启动时checker 的值为 1 时,函数将完全按照错误消息中的说明执行操作 - 它将返回未定义。通过阅读代码应该很容易看出这是如何发生的。

为了解决这个问题,我建议首先明确说明这个函数在调用时应该做什么。另外,我强烈建议消除对全局变量的依赖,除非您绝对确定自己了解自己在做什么以及它们的影响。

【讨论】:

  • 创建用户时触发。它生成一个随机变量,并设置为要添加到数据库中的对象userObject。然后我们返回一个 db 查询,检查生成的代码是否存在于数据库中。如果是,则 checker 设置为 1,并且生成的代码将添加到 Codes 下,并以用户 UID 作为键。否则检查器为零,循环继续。 checker 在开始时的值为 0。仅当不存在代码副本时才变为 1 以停止循环的执行
【解决方案2】:

前段时间我也遇到了同样的问题。 ESLint 不允许函数完成,因为它会评估代码的每个部分是否都返回一个 Promise。 从我可以看到 if 的第一部分确实返回了一些东西。尝试在 else 块中返回一个布尔值。

if (!snapshot.exists()){
                checker = 1;
                //add uCode into respective uid slot under Codes
                console.log(""+newRand+" : "+event.uid);
                return admin.database().ref('Codes/' + event.uid).set(userObject);

            }else{
                checker = 0;
                console.log("uCode "+newRand+" exists");
                console.log("uCode generation failed for: "+event.uid);
return false;
            }

【讨论】:

    猜你喜欢
    • 2019-10-28
    • 2019-11-18
    • 2018-12-03
    • 2019-08-12
    • 1970-01-01
    • 2018-04-18
    • 2018-12-05
    • 2021-12-13
    • 1970-01-01
    相关资源
    最近更新 更多