【发布时间】:2017-11-25 07:18:56
【问题描述】:
编辑:以下不是我真正的问题。查看答案。
我正在使用 Google firebase 开发一个简单的 html/javascript 聊天客户端。以下代码旨在成为注册和登录用户的基本系统,其中该函数在1 和2 位置提供了一个包含用户名和密码的数组($usr)。
然后根据数据库的结果(getuser 变量,结构为用户 obj)检查本地用户名和密码 $usr[1-2],以确定用户名是否已被使用或用户的凭据是否有效。请注意,这是一个个人项目,数据并非敏感数据。
//Registers user credentials with input [cmd, user, pass]
var auth = function ($usr) {
var db = firebase.database().ref('chatapp/users/' + $usr[1]);
var getuser;
user = {'name': $usr[1], 'pass': $usr[2]};
db.once('value').then(function(snapshot) {
getuser = snapshot.val();
if ($usr[0] === "/register") {
if (getuser.name !== $usr[1]) {
db.set(user);
notify('Registered ' + $usr[1] + ' with pass "' + $usr[2] + '"');
} else {
notify('Username "' + $usr[1] + '" already taken, try again');
}
} else if ($usr[0] === "/login") {
if (getuser.name !== $usr[1] || getuser.pass !== $usr[2]) {
notify('Invalid credentials ' + $usr[1] + ':' + $usr[2]);
} else {
notify($usr[1] + ' logged in');
}
}
});
};
问题在 db.once() 中起作用。正在检索数据,但已延迟。如果用户尝试注册 (getuser.name !== $usr1) 将始终返回 True,因为该变量设置为未定义。但是,登录命令完美无缺,因为此时 getuser 已设置为从 Firebase 检索到的值。
我尝试过仅使用 .once() 来设置变量,或者作为返回 snapshot.val() 的函数。我尝试将我的所有代码包含在 .once() 的回调中,并使用 snapshot.val()[name] 和 [pass] 而不是将其存储到变量中。唯一的解决方案似乎是手动中断程序流程。
此外,我还发现在 getuser.name 有效的情况下,使用 getuser[name] 不起作用,这毫无意义,进一步激怒了我。请帮忙,现在是凌晨 2 点 12 分。
Here is the official documentation. Here is a relevant Stackoverflow question, which may be the solution I'm looking for but I don't understand it.
真正让我感到困惑的是,.then 后面的函数据说依赖于被确认的数据,显然事实并非如此。
【问题讨论】:
-
获得快照后,数据不会延迟。您存储在变量中。您在某个地方还有另一个问题,但我无法很好地理解您的问题
-
@abeyaz 我告诉你事实并非如此。如果我在将快照保存到变量后立即发出警报,它将返回未定义。如果我稍后在流程中添加第二个警报,它将返回正确的对象。如果命令是 /register,getuser.name !== $usr[1] 将始终返回 true,但 /login 中的相同语句返回 true 或 false,具体取决于 getuser.name 的值(在第一个循环。
-
请把
console.log(snapshot.val(), getuser)放在getuser = snapshot.val();后面。因此,我们可以看到正在发生的事情并提出解决方案。 -
感谢您的帮助。我找到了一个我将更新的解决方案,我认为你是正确的,但它有一些怪癖。
标签: javascript database firebase asynchronous firebase-realtime-database