如何正确使用Firebase的.once()方法将检索到的值存储在Javascript中?

时间:2017-11-25 07:18:57

标签: javascript database firebase asynchronous firebase-realtime-database

编辑:以下不是我的真正问题。见答案。

我正在使用Google firebase开发一个简单的html / javascript聊天客户端。以下代码旨在成为注册和登录用户的基本系统,其中该函数提供了一个包含12位置的用户名和密码的数组($ usr)。 / p>

然后根据数据库的结果(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!== $ usr 1)将始终返回True,因为该变量设置为undefined。但是,login命令可以正常运行,因为当时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后面的函数应该依赖于被确认的数据,显然情况并非如此。

1 个答案:

答案 0 :(得分:0)

这是对我有用的代码:



//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 === null) {
				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');
			}
		}
	});
};




问题实际上不是我的问题。是什么让我相信数据的检索被推迟是因为我的代码最初不在.once()方法的回调函数之内。如果使用.once()的回调函数将snapshot.val()写入变量,然后将其余代码写入回调函数之外,则数据将异步写入,并且您的变量将是设置为undefined,直到可以从服务器检索真值。我认为解决这个问题的方法是在回调中调用带有参数snapshot.val()的函数,或者只是在回调中编写代码(上图)。

我的代码的实际问题在于行if (getuser.name !== $usr[1])。如果getuser的值为null,则会导致错误。固定代码在上面。