java - 使用现有用户登录应用程序 - phone Auth Firebase Android -
问题描述
我正在开发一个使用 firebase phone auth 方法的应用程序。它适用于第一次使用的用户,他们获得短信代码并在 firebase 控制台中注册。但是,如果他们注销或重新安装应用程序,他们将无法访问应用程序菜单,因为它们已经在 firebase 控制台数据库中。
我不知道如何告诉应用程序用户是否已经注册,然后对主要活动进行意图,如果未注册,则转到注册活动。我知道如何获取当前用户,但如果用户存在于 firebase 数据库中,我不知道如何跳过验证步骤。
希望你能得到我。
这是我的代码。
private static final String KEY = "userAuth";
private static final String TAG = "PhoneAuthActivity";
private static final String KEY_VERIFY_IN_PROGRESS = "key_verify_in_progress";
// [START declare_auth]
private FirebaseAuth mAuth;
// [END declare_auth]
private boolean mVerificationInProgress = false;
private String mVerificationId;
private PhoneAuthProvider.ForceResendingToken mResendToken;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
// Instance of Firebase
private PhoneAuthProvider phoneAuthProvider;
private String verificationId;
// id user from DB
private String idUser;
private EditText activationCode;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_verify_code);
// Restore instance state
if (savedInstanceState != null) {
onRestoreInstanceState(savedInstanceState);
}
// [START initialize_auth]
// Initialize Firebase Auth
mAuth = FirebaseAuth.getInstance();
// [END initialize_auth]
// Initialize phone auth callbacks
// [START phone_auth_callbacks]
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(PhoneAuthCredential credential) {
// This callback will be invoked in two situations:
// 1 - Instant verification. In some cases the phone number can be instantly
// verified without needing to send or enter a verification code.
// 2 - Auto-retrieval. On some devices Google Play services can automatically
// detect the incoming verification SMS and perform verification without
// user action.
Log.d(TAG, "onVerificationCompleted:" + credential);
// [START_EXCLUDE silent]
mVerificationInProgress = false;
// [END_EXCLUDE]
signInWithPhoneAuthCredential(credential);
}
@Override
public void onVerificationFailed(FirebaseException e) {
// This callback is invoked in an invalid request for verification is made,
// for instance if the the phone number format is not valid.
Log.w(TAG, "onVerificationFailed", e);
// [START_EXCLUDE silent]
mVerificationInProgress = false;
// [END_EXCLUDE]
if (e instanceof FirebaseAuthInvalidCredentialsException) {
} else if (e instanceof FirebaseTooManyRequestsException) {
// The SMS quota for the project has been exceeded
// [START_EXCLUDE]
Snackbar.make(findViewById(android.R.id.content), "Quota exceeded.",
Snackbar.LENGTH_SHORT).show();
// [END_EXCLUDE]
}
}
@Override
public void onCodeSent(@NonNull String verificationId,
@NonNull PhoneAuthProvider.ForceResendingToken token) {
// The SMS verification code has been sent to the provided phone number, we
// now need to ask the user to enter the code and then construct a credential
// by combining the code with a verification ID.
Log.d(TAG, "onCodeSent:" + verificationId);
// Save verification ID and resending token so we can use them later
mVerificationId = verificationId;
mResendToken = token;
}
};
// [END phone_auth_callbacks]
activationCode = findViewById(R.id.eTextActivCode);
progressBar = findViewById(R.id.progressBar);
String phone = getIntent().getStringExtra("phone");
idUser = getIntent().getStringExtra("user");
sendVerificationCode(phone);
}
// [START on_start_check_user]
@Override
public void onStart() {
super.onStart();
// Check if user is signed in (non-null) and update UI accordingly.
FirebaseUser currentUser = mAuth.getCurrentUser();
if(currentUser != null){
Intent intent = new Intent(VerifyCodeActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra("user", idUser);
startActivity(intent);
}
// [START_EXCLUDE]
if (mVerificationInProgress) {
startPhoneNumberVerification(getIntent().getStringExtra("phone"));
}
// [END_EXCLUDE]
}
// [END on_start_check_user]
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(KEY_VERIFY_IN_PROGRESS, mVerificationInProgress);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mVerificationInProgress = savedInstanceState.getBoolean(KEY_VERIFY_IN_PROGRESS);
}
private void startPhoneNumberVerification(String phoneNumber) {
// [START start_phone_auth]
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
mCallbacks); // OnVerificationStateChangedCallbacks
// [END start_phone_auth]
mVerificationInProgress = true;
}
private void verifyPhoneNumberWithCode(String verificationId, String code) {
// [START verify_with_code]
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
// [END verify_with_code]
signInWithPhoneAuthCredential(credential);
}
// [START resend_verification]
private void resendVerificationCode(String phoneNumber,
PhoneAuthProvider.ForceResendingToken token) {
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
mCallbacks, // OnVerificationStateChangedCallbacks
token); // ForceResendingToken from callbacks
}
// [END resend_verification]
// [START sign_in_with_phone]
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
if (task.isSuccessful() || activationCode.equals("123456")) {
Intent intent = new Intent(VerifyCodeActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra("user", idUser);
startActivity(intent);
} else {
Toast.makeText(VerifyCodeActivity.this, task.getException().getMessage(),
Toast.LENGTH_LONG).show();
}
} else {
// Sign in failed, display a message and update the UI
Log.w(TAG, "signInWithCredential:failure", task.getException());
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
// The verification code entered was invalid
// [START_EXCLUDE silent]
activationCode.setError("Ingresa un código válido.");
// [END_EXCLUDE]
}
}
}
});
}
// [END sign_in_with_phone]
public void verifyPhoneNumber(View view) {
String code = activationCode.getText().toString();
if (code.isEmpty() || code.length() < 6) {
activationCode.setError("Ingresa un código correcto");
activationCode.requestFocus();
return;
}
verifyPhoneNumberWithCode(mVerificationId, code);
}
public void resendActivationCode(View view){
resendVerificationCode(getIntent().getStringExtra("phone"), mResendToken);
}
private void sendVerificationCode(String number) {
// Initialize Firebase Auth
phoneAuthProvider = PhoneAuthProvider.getInstance();
phoneAuthProvider.verifyPhoneNumber(number, 60, TimeUnit.SECONDS,
TaskExecutors.MAIN_THREAD, mCallback);
}
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallback = new
PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken
forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
verificationId = s;
}
@Override
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
String code = phoneAuthCredential.getSmsCode();
if (code != null) {
progressBar.setVisibility(View.VISIBLE);
//verifyCode(code);
}
}
@Override
public void onVerificationFailed(FirebaseException e) {
Toast.makeText(VerifyCodeActivity.this,
"Error al verificar el número de teléfono: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
};
} ```
解决方案
取决于您的问题和评论,您需要知道用户之前是否已经登录或者是第一次登录,并且您没有服务器数据库来保存用户数据
但是如果你使用另一个服务器数据库,我会给你两个答案
注意:在您的问题中,您写的是您希望用户在第二次登录时进入菜单活动而无需验证但依赖是不可能发生的,因为这样任何人都可以使用任何电话号码并登录,所以使用电话的验证码就像密码和电子邮件以确保身份验证成功
1.第一个解决方案:如果您在第一次用户登录时有另一个数据库服务器,您将在您的数据库中保存用户数据,如姓名和电话、位置、uid ......等,这样您就可以通过uid将用户 bwtween firebase phone auth 与数据库绑定或电话,现在当用户第二次通过firebase登录时,您将通过uid或电话检查用户是否已经在您的数据库中(不是第一次)或不是(用户第一次)。
- 第二种解决方案:使用AdditionalUserInfo检查用户是 newUser 还是在尝试进入
signInWithCredential
内部之前登录onComplete
像这样
OnCompleteListener<AuthResult> completeListener = new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
boolean isNew = task.getResult().getAdditionalUserInfo().isNewUser();
Log.d("MyTAG", "onComplete: " + (isNew ? "new user" : "old user"));
}
}
};
我希望这对你有帮助
推荐阅读
- python - 以下代码给了我一个错误:'list' object has no attribute 'split'
- excel - 如何仅检索 Excel for Python 中的可见单元格?
- ios - Swift:如何编码对象,与原始对象比较只有不同的属性
- html - 如何插入仅给出 XPath 的 html 元素?
- javascript - 创建一个无限的水平滚动画廊
- javascript - 如何将“RegExp.test”部分应用于字符串?
- cuda - 如何在 CUDA 设备代码中使用 Try-Catch 之类的东西
- git - git log 显示所有_except_标签
- validation - 如何解决 createState 函数...返回旧的或无效的状态实例?
- java - 我正在编译电子商务应用程序,但在 gradle 控制台中出现以下错误