如何了解电子邮件是否已在Firebase简单登录中注册



我正在为一个html5手机应用程序使用firebase(带有Angularfire)。用户在开始屏幕中只输入他们的电子邮件,然后,根据该电子邮件是否已经注册,用户将分别重定向到登录页面或注册页面。对于步骤1,我们如何查询firebase简单登录以确定电子邮件是否已注册?

2018年7月19日更新

前面提到的方法已弃用。现在使用fetchSignInMethodsForEmail。

2016年6月26日更新

自从这篇文章最初发布以来,发生了很多变化,Firebase身份验证不再被称为Firebase简单登录。

此外,看起来有一种新的方法可用fetchProvidersForEmail,它可能会为这个问题提供解决方案。

来自文档:

fetchProvidersForEmail(电子邮件)返回firebase。Promise包含字符串的非空数组

获取可用于登录给定电子邮件地址的提供程序ID的列表。对于";标识符第一";登录流程。

我还没有测试过这一点,但我想如果您调用该方法并接收到一组提供程序,那么电子邮件必须已经在一个或多个身份验证提供程序中注册。

旧答案

我不相信你可以在不尝试实际登录或注册用户的情况下直接查询Firebase Simple Login来获取这些信息。

您需要做的是在注册过程中存储一个已注册电子邮件的列表,然后查询该列表。然后,您可以查询该路径,如果它返回数据,则它存在,否则它不存在。

遵循#Kato和#MikePugh的评论建议,我将编写这个解决方案,它对我有效。

Solutio#1(强烈推荐)

mAuth.fetchProvidersForEmail("emailaddress@gmail.com").addOnCompleteListener(new OnCompleteListener<ProviderQueryResult>() {
@Override
public void onComplete(@NonNull Task<ProviderQueryResult> task) {
if(task.isSuccessful()){
///////// getProviders().size() will return size 1. if email ID is available. 
task.getResult().getProviders().size();
}
}
});

解决方案#2

创建一个伪FirebaseUser对象。

FirebaseUser firebaseUser = null;
private FirebaseAuth mAuth;
private void isEmailAlreadyUsed() {
mAuth = FirebaseAuth.getInstance();
///// here I am gonna create dummy user at **Firebase** with the Entered email Id (Email to check against) 
mAuth.createUserWithEmailAndPassword(mEmailView.getText().toString(), "dummypass")
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
Log.d(TAG, "createUser:onComplete:" + task.isSuccessful());

if (task.isSuccessful()) {
/////user do not exit so good to initialize firebase user.              
firebaseUser = task.getResult().getUser();
} else {
if(task.getException().getMessage().equals("The email address is already in use by another account.")) {
Log.d(TAG, "This email ID already used by someone else");     
}
}
}
});
}

稍后,当用户输入密码并按下SIGNUP按钮时,您就可以更新设置为dummpass的用户密码。

boolean isSignUpMade = false;
if (firebaseUser != null)
firebaseUser.updatePassword(password)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
signUpCallProgress.setVisibility(View.VISIBLE);
if (task.isSuccessful()) {
isSignUpMade = true;
Log.d(TAG, "User password updated.");
} else {
isSignUpMade = false;
Log.d(TAG, "User password not updated.");
}
}
});

您可以看到,我使用了isSingUpMade变量,只是为了确保用户按下SINGUP按钮。

如果用户想在没有注册的情况下离开,则必须从FIREBASE服务器中删除该虚拟用户。

这就是逻辑。

@Override
public void onBackPressed() {
if (!isSignUpMade) {
if (firebaseUser != null)
firebaseUser.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User account deleted.");
}
}
});
}
super.onBackPressed();
}

一个更容易理解的示例,用于了解如何在使用电子邮件/密码注册时捕获用户是否已经存在

  1. 发现错误
  2. 如果存在"身份验证/电子邮件已在使用">
  3. 调用另一个包含.signInWithEmailAndPassword()的函数

示例

.createUserWithEmailAndPassword(email, password)
.catch(error => {
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
// Catch this errorCode to know if user exists
if (errorCode === 'auth/email-already-in-use') {
// Call function X to sign user in instead
signInMail(email, password);
return;
} 
// Weak password?
else if (errorCode == 'auth/weak-password') {
console.log('The password is too weak.');
} 
else {
console.log(errorMessage);
}
console.log(error);
})

您想在自己的代码中使用的重要部分是这个

.catch(error => {
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
if (errorCode === 'auth/email-already-in-use') {
console.log('This email is already in use');
// Your action
return;
}
})

服务

import {
AbstractControl,
AsyncValidatorFn,
} from '@angular/forms';
import { Observable, of, timer, from } from "rxjs";
import { map, switchMap } from "rxjs/operators";
import { Auth, fetchSignInMethodsForEmail } from '@angular/fire/auth';
@Injectable({
providedIn: "root"
})
export class EmailValidators {
constructor(
private auth: Auth,
) {
}
public searchEmailAddress(emailAddress: string): Observable<Array<string>> {
console.log(`searchUser >> emailAddress = ${emailAddress}`);
if (emailAddress) {
// debounce
return timer(1000)  // wait 1 second before searching to reduce API requests
.pipe(
switchMap(() => {
return from(fetchSignInMethodsForEmail(this.auth, emailAddress));
})
);
} else {
return of([]);
}
}
public emailValidator(): AsyncValidatorFn {
return (control: AbstractControl): Observable<any> => {
return this.searchEmailAddress(control.value)
.pipe(
map((res: Array<string>) => {
console.log(res);
// if sign-in methods exist for the email address, it is used
if (res.length) {
// return error
return { emailExists: true };
} else {
return null;
}
})
);
};
}
}

组件TypeScript

import {
FormGroup,
FormBuilder,
Validators,
} from '@angular/forms';
import { EmailValidators } from "../server.service";
export class NewAccountComponent {
public NewAccountForm: FormGroup;
constructor(
private emailValidators: EmailValidators,
private formBuilder: FormBuilder,
) {
this.NewAccountForm = this.formBuilder.group({
emailAddress: [
"",
Validators.compose(
[Validators.required, Validators.email],
),
this.emailValidators.emailValidator() // custom async validator
],
firstName: "",
lastName: "",
password: "",
confirmPassword: "",
agreePrivacyPolicy: false,
});
}
}

组件HTML

<form [formGroup]="NewAccountForm" (ngSubmit)="onSubmit(NewAccountForm)">
<!-- emailAddress -->
<div class="row mt-1 justify-content-center">
<div class="col">
<kendo-floatinglabel text="Email Address" class="w-75">
<input kendoTextBox #emailChild type="email" formControlName="emailAddress" autocomplete="email" [email]="true"
required />
</kendo-floatinglabel>
</div>
</div>
<!-- Check if email address exists -->
<div class="row mt-2 justify-content-center">
<div class="col">
<div *ngIf="NewAccountForm.get('emailAddress')!.pending" class="cross-validation-error-message alert alert-info">
Searching...
</div>
<div *ngIf="NewAccountForm.get('emailAddress')!.errors?.emailExists"
class="cross-validation-error-message alert alert-danger">
Email address has already been used.
</div>
</div>
</div>
<!-- other fields and submit ... -->
</form>

您可以在registerActivity中的register()_method之前添加以下代码。

FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if(email.equals(user.getEmail().trim())) {
Toast.makeText(this, "Email is taken", Toast.LENGTH_SHORT).show();
return;
}

最新更新