Firebase值未定义时未定义

时间:2017-11-30 05:33:27

标签: 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 = 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数据库中,名称值不为null。它添加了一个字符串。

4 个答案:

答案 0 :(得分:1)

您很可能尝试在调用program函数的代码中使用返回的名称。 E.g。

var name = program("1234");
console.log(name); // this will print undefined

这不起作用,因为您的program()实际上并没有返回名称。数据是从Firebase异步加载的。当program()退出时,数据尚未加载。

最简单的方法是在代码中加入一些日志语句:

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)使用回调的原因,例如您传递给on()的回调。当数据可用时,将调用此回调,并且该回调是您可以访问用户数据的唯一位置。因此,任何需要刚刚加载的数据的代码都必须内部进行回调,或者从该回调中调用。 E.g。

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

}

答案 1 :(得分:0)

火力地堡>数据库>作用

您是否更改了规则的价值?

enter image description here

评论示例!

移动到名字后可以获得该值。

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

如果没有,请让它担心。

答案 2 :(得分:0)

您应该收到返回的值。

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 name获取值。或者只是返回return ref.on('value' ...

答案 3 :(得分:0)

我与Frank reason的第二个问题是你的函数program()无效的原因。由于ref.on('value'...进行异步调用,program()不会等待ref.on完成,并且存在undefined返回值。

你可以做的是使用Promises。将您的program()函数中的语句包含在Promise中,并在完成异步调用后,resolvereject根据它给出的结果。

这是Promise的功能:

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语句中执行此块。如果你正在使用Promises,你还需要研究如何在循环中使用Promises。如需参考,请查看Promise.all()