所以我遇到的问题是我有一个注册表,用户可以在其中输入信息(其中还包含电子邮件)。
我有一个名为的onClick方法
public void onCreateAccount(View view);
当用户单击“注册”时,它将验证表单上的字段。
public class Foo extends AppCompatActivity {
//OTHER PRIVATE MEMBERS
private EditText etEmail;
boolean isValid;
private DatabaseReference databaseUser = FirebaseDatabase.getInstance().getReference().child("User");
@Override
protected void onCreate(Bundle savedInstanceState) {
//DOES SOME INITIALIZATION
}
public void onCreateAccount(View view){
String email = etEmail.getText().toString().trim();
if(validateEmail(email)){
String id = databaseUser.push().getKey();
User user = new User(id, email);
databaseUser.child(user.getId()).setValue(user);
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.putExtra("isCreateAccount", true);
startActivityForResult (intent,0);
}
}
private boolean validateEmail(String email) {
isValid = true;
databaseUser.orderByChild("email").equalTo(emailUserEntered).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists())
isValid=false;
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
在将记录插入Firebase数据库之前,我想先检查电子邮件是否已经存在,然后再插入。因此,输入电子邮件= a@mail.com的人将不允许这样做。
答案 0 :(得分:1)
数据是从Firebase异步加载的,因此无法在Android上使用类似boolean validateEmail(String email)
的方法。从数据库中加载数据必须是一项阻止操作才能启用这种方法,而Android不允许阻止操作(因为这会使手机无法操作)。
因此,您必须*要么(移动代码以将用户创建为 validateEmail
或传入自定义界面,然后调用一次数据库的结果返回了。最后一个的代码如下。
首先,我们将创建一个自定义界面,您可以在需要检查用户是否已经存在的任何地方实施该界面。
public interface UserExistsCallback {
void onCallback(boolean value);
}
该界面可以根据需要是特定的还是通用的。它与Firebase的ValueEventListener
非常相似,但是此接口仅供您自己使用。
使用此接口,我们可以像这样定义validateEmail
方法:
private void validateEmail(String email, final UserExistsCallback callback) {
isValid = true;
databaseUser.orderByChild("email").equalTo(emailUserEntered)
.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
callback.onCallback(dataSnapshot.exists())
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
}
然后像这样从onCreateAccount
调用它:
public void onCreateAccount(View view){
String email = etEmail.getText().toString().trim();
validateEmail(email), new UserExistsCallback() {
public void onCallback(boolean exists) {
if (!exists) {
String id = databaseUser.push().getKey();
User user = new User(id, email);
databaseUser.child(user.getId()).setValue(user);
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.putExtra("isCreateAccount", true);
startActivityForResult (intent,0);
}
})
}
}
另请参阅以下许多(链接的)答案:
答案 1 :(得分:0)
阻止用户登录(如果存在此类电子邮件)应该很简单,您可以使用如下代码进行操作:
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference().child("User");
boolean flag=false;
databaseReference.orderByChild("email").equalTo(emailUserEntered).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists())
flag=true;
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
return flag;
但是,如果您希望阻止用户在未进行身份验证的情况下中途编写数据库中的电子邮件,这将非常困难。
您必须逐个字母对数据库进行检查,这不仅会降低效率,而且从最后看也不是一件好事。
编辑:
数据是从Firebase异步加载的,因此您应该在if(dataSnapshot.exists())
内放置类似的内容,以避免当前遇到的问题。
if(validateEmail(email)){
String id = databaseUser.push().getKey();
User user = new User(id, email);
databaseUser.child(user.getId()).setValue(user);
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.putExtra("isCreateAccount", true);
startActivityForResult (intent,0);
}
else
Toast(YourActivity.this, "Email already exists", LENGTH_LONG).show();
答案 2 :(得分:0)
在电子邮件字段上具有索引。然后,您可以进行查询以通过电子邮件查找。
这将提高性能,因为不需要遍历所有子级。
类似的东西:
orderByChild('email').equalTo(email).once('value').exist();
答案 3 :(得分:0)
此方法仅用于身份验证:firebase.auth().fetchProvidersForEmail("emailaddress@gmail.com")