我正在尝试使用界面异步检查Firebase数据库中的条目,但是我不确定如何以与密码和电子邮件相同的方式实现该条目。
示例:
if (TextUtils.isEmpty(password) || !isPasswordValid(password)) {
mPasswordView.setError(getString(R.string.error_invalid_password));
focusView = mPasswordView;
cancel = true;
}
private boolean isPasswordValid(String password) {
// Add logic to check for a valid password (minimum 8 characters)
String confirmPassword = mConfirmPasswordView.getText().toString();
return (confirmPassword.equals(password)) && (password.length() > 7) && (password != "12345678") && (password != "password");
}
我试图用用户名创建类似的方法,该方法检查Firebase中输入的用户名,如果找到数据,则返回true。我创建了一个方法(fetchUsername)来检查Firebase在后台线程上的名称,但是无法弄清楚如何将结果正确地传递回最终方法并返回一个布尔值。我相信我犯了一个愚蠢的语法错误,但我看不到它。这是我所拥有的:
private boolean isUsernameDuplicate(final String username) {
boolean userIsOnFirebase ( boolean isOnFirebase){ ///<----line that won't take, wants semicolon after variable
if (isOnFirebase) {
return true;
} else {
return false;
}
}
fetchUsername(username, new FirebaseSuccessListener() {
@Override
public void onDataFound(boolean isDataFetched) {
if (isDataFetched) {
userIsOnFirebase(true);
} else {
userIsOnFirebase(false);
}
}
});
return userIsOnFirebase;
}
private void fetchUsername(final String username, final FirebaseSuccessListener dataFetched) {
//checks database for username
mReference = FirebaseDatabase.getInstance().getReference().child("users").child("username");
mReference.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
dataFetched.onDataFound(true);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
public interface FirebaseSuccessListener {
void onDataFound(boolean isDataFetched);
}
编辑:这是我的解决方案:
//member Variables
String checkedUsername;
private void attemptRegistration() {
// Reset errors displayed in the form.
mEmailView.setError(null);
mPasswordView.setError(null);
checkedUsername=null;
// Store values at the time of the login attempt.
String email = mEmailView.getText().toString();
String password = mPasswordView.getText().toString();
String username = mUsernameView.getText().toString();
boolean cancel = false;
View focusView = null;
if (TextUtils.isEmpty(username)) {
mUsernameView.setError(getString(R.string.error_field_required));
focusView = mUsernameView;
cancel = true;
}
if (!isUsernameValid(username)) {
mUsernameView.setError("Username is taken");
focusView = mUsernameView;
cancel = true;
}
private boolean isUsernameValid(String username) {
if (!duplicateUsername(username)) {
return true;
} else {
Toast.makeText(this, "Username is taken", Toast.LENGTH_LONG);
return false;
}
}
private boolean duplicateUsername(String username) {
if (fetchUsername(username) != null) {
return true;
}
return false;
}
private String fetchUsername(final String username) {
//checks database for username
mReference = FirebaseDatabase.getInstance().getReference().child("users");
mReference.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
User user = new User();
user = dataSnapshot.getValue(User.class);
if (user.getUsername() == username) {
checkedUsername = user.getUsername();
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
return checkedUsername;
}
答案 0 :(得分:1)
这是一个解释。首先,field
变量是在variable
内部创建的class
,并且该class
的所有成员都可以访问。另一方面,在variable
内部创建的method
只能由该方法的成员访问,而不能访问class
的其余成员。
Firebase异步运行(读取和写入数据库),并实现自己的callbacks
,这些UI在UI线程上被调用。例如,您可以实现的回调之一(取决于场景)是:onSuccessListener
,addOnFailureListener
,onCompleteListener
,onDataChange
。 callbacks
可以为您提供来自Firebase(在本例中为数据库)的信息,写入成功或读取成功,并且您已准备好在应用程序中使用数据或出现问题。在这些callbacks
中,您可以轻松更新UI。
您现在正在做的是创建一个interface
,它将在触发该callbacks
时触发,这是不必要的步骤,因为您可以轻松更新{{1 }}。
在您要返回用户名的位置创建的方法也无法按预期工作。为什么?因为部分代码callback
是在数据库返回结果之前执行的。如您所知,return fetchedusername
是异步运行的,需要通过Internet获取数据,同时Fireabse
已经执行。这就是为什么您有return fetchedusername
个方法的原因。
希望这可以清除一些东西。