Javascript 当Firebase值不应为时,它是未定义的

Javascript 当Firebase值不应为时,它是未定义的,javascript,function,firebase,firebase-realtime-database,undefined,Javascript,Function,Firebase,Firebase Realtime Database,Undefined,我正在做一个firebase项目。在测试过程中 return user.val().name; 将返回一个 undefined 然而价值 console.log(user.val().name) 将返回存储在.name字段中的实际字符串。这是为什么。即使指定 user.val().name 对于一个变量,该变量仍然未定义。请帮助找出发生这种情况的原因。我正在将其打印到csv 这是我的密码: var database = firebase.database(); var ref2 =

我正在做一个firebase项目。在测试过程中

return user.val().name;
将返回一个

undefined 
然而价值

console.log(user.val().name) 
将返回存储在.name字段中的实际字符串。这是为什么。即使指定

user.val().name
对于一个变量,该变量仍然未定义。请帮助找出发生这种情况的原因。我正在将其打印到csv

这是我的密码:

var database = firebase.database();
var ref2 = database.ref('information/');

var id;
var name;

ref2.on("value", function (one) {

    one.forEach(function (two) {

        if (typeof two.val().Id !== 'undefined') {
            id = two.val().Id;
            name = program(id); //name undefined

        }
        else {
           id = "";
        }

        csv = name + "," + id +"\n";


    });

    download(csv);

});
};


function program (id) {

var database = firebase.database();
var ref = database.ref("users/" + id + "/");

ref.on('value',function(user){

    if (typeof user.val().name === 'undefined') {
        return null;
    }
    else {
        console.log(user.val().name); //this doesnt show undefined
        return user.val().name; //this shows undefined when appended to a html element

    }
})
}

注意:在firebase数据库中,名称值不为空。它添加了一个字符串

Firebase>数据库>角色

你改变了规则的价值吗

评论示例

它可以在移动到name后获取值

   var ref = database.ref ("users/" + id + "/name");
   ref.on ('value', function (user) {
       if (user.val ()! = null) {
            console.log (user.val ())
        }
   }

如果没有,让我们担心一下。

您应该会收到返回的值

var name = ref.on('value',function(user){

    if (typeof user.val().name === 'undefined') {
        return null;
    }
    else {
        console.log(user.val().name); //this doesnt show undefined
        return user.val().name; //this shows undefined when appended to a html element

      }
})

然后使用
返回名称
获取值。或者只需返回
return ref.on('value')…

,很可能您正试图在调用
程序
函数的代码中使用返回的名称

var name = program("1234");
console.log(name); // this will print undefined
这将不起作用,因为您的
程序()
实际上没有返回名称。数据是从Firebase异步加载的。当
程序()
退出时,数据尚未加载

通过在代码中加入一些日志语句,最容易看出这一点:

function program (id) {
    var database = firebase.database();
    var ref = database.ref("users/" + id + "/");
    console.log("Before attaching listener");    
    ref.on('value',function(user){
        console.log("Got value from database");
    })
    console.log("After attaching listener, exiting function");    
}
这将打印:

在附加侦听器之前

附加侦听器后,退出函数

从数据库中获取值

这可能不是您期望的顺序,但它正在按设计工作。而不是等待加载数据(并让浏览器/用户等待),代码将继续。然后,当加载数据时,将调用回调。但在原始代码中,这意味着您的
return
语句无法将名称返回给原始调用方

这正是Firebase数据库(和大多数web API)使用回调的原因,就像您传递到()。此回调在数据可用时调用,并且是您可以访问用户数据的唯一位置。因此,需要您刚才加载的数据的任何代码必须位于该回调中,或者从该回调中调用。例如

function program (id) {

    var database = firebase.database();
    var ref = database.ref("users/" + id + "/");
    
    ref.on('value',function(user){
    
        if (typeof user.val().name === 'undefined') {
            return null;
        }
        else {
            console.log(user.val().name);
            appendToHtmlElement(user.val().name);
        }
    })

}
我支持Frank关于函数
program()
不工作的原因的观点。因为
ref.on('value')…
进行异步调用,
program()
不等待
ref.on
的完成,而是以
未定义的返回值存在

您可以改为使用承诺。将
program()
函数中的语句封装在承诺中,并在异步调用完成后,根据它给出的结果,
resolve
reject

以下是您的承诺功能:

function program(id) {
    return new Promise(function (resolve, reject) {
        try {
            var database = firebase.database();
            var ref = database.ref("users/" + id + "/");

            ref.on('value', function (user) {
                if (typeof user.val().name === 'undefined') {
                    resolve(null);
                } else {
                    console.log(user.val().name);
                    resolve(user.val().name);
                }
            })
        } catch (e) {
            reject(e)
        }
    });
}
然后,下面是如何读取结果:

program(id).then(function (result) {
        console.log(result)
        //Do what you want with the result here
    }).catch(function (error) {
        console.log(error)
})

注意:您在for each语句中执行此块。如果您使用承诺,还需要了解如何在循环中使用承诺。请选中
Promise.all()

作为参考,您如何显示此返回值?返回值被分配给一个var“name”。然后我将var名称打印到csv文件中。我可以看一下显示此内容的html吗?可以。规则已更改为公共访问(即更改为您显示的内容)。它仍然不会运行。user.val()返回“null”还是user.val()返回“undefined”?在移动到name.the user.val()后可以获取值不会返回null。它会打印“name”字段的值。这可能是一个好方法。请您进一步解释。我想我已经掌握了它的窍门。更多的解释会更好。请尝试一下。我认为我没有真正解释我的问题。我编辑了我的代码,以反映我的程序运行环境(id)正在调用函数。谢谢。这是一个好主意。我将研究promise。谢谢。