对于一个客户端项目,我正在创建一个简单的混合应用程序,它提供一个非常简单的功能,但是流量很高。这个应用程序通常不需要后端,因为它非常简单,而且firebase似乎是该项目的完美解决方案。
我唯一坚持的部分是使用Firebase的SMS验证/身份验证。然而,在进行了大量的谷歌搜索和文档阅读之后,我开始意识到,要做到这一点并没有什么简单的方法。下面是我到目前为止研究的内容:
通常在混合移动应用程序中,它们或JS的非本地特性是罪魁祸首,但第一次(至少对我来说)感觉并非如此。在这一点上,我认为Firebase不是一个有效的选择,但是在开始研究AWS并为客户端设置一个完整的后端之前,我想最后一次询问社区中充满爱心和关爱的成员。
除了中间服务/没有后端服务器之外,还有其他方法来处理这种类型的身份验证吗?有人有使用这些解决方案的经验吗?
更新:2017年5月
电话验证和身份验证现在在Firebase中本机可用。见下面我自己贴出的答案。
更新:2017年4月
Firebase现在本机支持云函数。现在,您可以在不设置任何服务器的情况下使用云函数来完成这一任务和更多的任务。
更新:2017年10月
Fabric.io和Firebase合作并集成了Firebase电话身份验证中的数字,并为Fabric推出了更多功能。
发布于 2017-08-03 22:57:20
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.FirebaseException;
import com.google.firebase.FirebaseTooManyRequestsException;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthProvider;
import java.util.concurrent.TimeUnit;
public class PhoneAutenticationService {
public PhoneAutenticationService(Activity activity,FirebaseAuth auth) {
this.activity = activity;
this.mAuth = auth;
setupCallback();
}
private static final String TAG = PhoneAutenticationService.class.getSimpleName();
private Activity activity;
private String verificationCode;
private static final String KEY_VERIFY_IN_PROGRESS = "key_verify_in_progress";
private static final int STATE_INITIALIZED = 1;
private static final int STATE_CODE_SENT = 2;
private static final int STATE_VERIFY_FAILED = 3;
private static final int STATE_VERIFY_SUCCESS = 4;
private static final int STATE_SIGNIN_FAILED = 5;
private static final int STATE_SIGNIN_SUCCESS = 6;
// [START declare_auth]
private FirebaseAuth mAuth;
// [END declare_auth]
private boolean mVerificationInProgress = false;
private String mVerificationId;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
private PhoneAuthProvider.ForceResendingToken mResendToken;
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(KEY_VERIFY_IN_PROGRESS, mVerificationInProgress);
}
protected void onRestoreInstanceState(Bundle savedInstanceState) {
mVerificationInProgress = savedInstanceState.getBoolean(KEY_VERIFY_IN_PROGRESS);
}
// [START on_start_check_user]
public void onStart(EditText mPhoneNumberField) {
// Check if user is signed in (non-null) and update UI accordingly.
FirebaseUser currentUser = mAuth.getCurrentUser();
updateUI(currentUser);
// [START_EXCLUDE]
if (mVerificationInProgress && validatePhoneNumber(mPhoneNumberField)) {
startPhoneNumberVerification(mPhoneNumberField.getText().toString());
}
// [END_EXCLUDE]
}
// [END on_start_check_user]
private void setupCallback(){
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 verificaiton without
// user action.
Log.d(TAG, "onVerificationCompleted:" + credential);
// [START_EXCLUDE silent]
mVerificationInProgress = false;
// [END_EXCLUDE]
// [START_EXCLUDE silent]
// Update the UI and attempt sign in with the phone credential
updateUI(STATE_VERIFY_SUCCESS, credential);
// [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) {
// Invalid request
// [START_EXCLUDE]
Toast.makeText(activity,"Invalid phone number.",Toast.LENGTH_SHORT).show();
// [END_EXCLUDE]
} else if (e instanceof FirebaseTooManyRequestsException) {
// The SMS quota for the project has been exceeded
// [START_EXCLUDE]
Toast.makeText(activity,"Quota exceeded.",Toast.LENGTH_SHORT).show();
// [END_EXCLUDE]
}
// Show a message and update the UI
// [START_EXCLUDE]
updateUI(STATE_VERIFY_FAILED);
// [END_EXCLUDE]
}
@Override
public void onCodeSent(String verificationId,
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);
Toast.makeText(activity,"onCodeSent:" + verificationId,Toast.LENGTH_SHORT).show();
verificationCode = verificationId;
// Save verification ID and resending token so we can use them later
mVerificationId = verificationId;
setVerificationCode(verificationId);
mResendToken = token;
// [START_EXCLUDE]
// Update UI
updateUI(STATE_CODE_SENT);
// [END_EXCLUDE]
}
};
}
public void startPhoneNumberVerification(String phoneNumber) {
// [START start_phone_auth]
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
activity, // Activity (for callback binding)
mCallbacks); // OnVerificationStateChangedCallbacks
// [END start_phone_auth]
mVerificationInProgress = true;
}
public 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]
public void resendVerificationCode(String phoneNumber,
PhoneAuthProvider.ForceResendingToken token) {
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
activity, // Activity (for callback binding)
mCallbacks); // resending
// [END start_phone_auth]
}
// [END resend_verification]
// [START sign_in_with_phone]
public void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(activity, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithCredential:success");
Toast.makeText(activity,"signInWithCredential:success",Toast.LENGTH_SHORT).show();
FirebaseUser user = task.getResult().getUser();
// [START_EXCLUDE]
updateUI(STATE_SIGNIN_SUCCESS, user);
// [END_EXCLUDE]
} 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]
Toast.makeText(activity,"Invalid code.",Toast.LENGTH_SHORT).show();
// [END_EXCLUDE]
}
// [START_EXCLUDE silent]
// Update UI
updateUI(STATE_SIGNIN_FAILED);
// [END_EXCLUDE]
}
}
});
}
// [END sign_in_with_phone]
public void signOut() {
mAuth.signOut();
updateUI(STATE_INITIALIZED);
}
private void updateUI(int uiState) {
updateUI(uiState, mAuth.getCurrentUser(), null);
}
public void updateUI(FirebaseUser user) {
if (user != null) {
updateUI(STATE_SIGNIN_SUCCESS, user);
} else {
updateUI(STATE_INITIALIZED);
}
}
private void updateUI(int uiState, FirebaseUser user) {
updateUI(uiState, user, null);
}
private void updateUI(int uiState, PhoneAuthCredential cred) {
updateUI(uiState, null, cred);
}
private void updateUI(int uiState, FirebaseUser user, PhoneAuthCredential cred) {
switch (uiState) {
case STATE_INITIALIZED:
// Initialized state, show only the phone number field and start button
Toast.makeText(activity,"Initialized state",Toast.LENGTH_SHORT).show();
break;
case STATE_CODE_SENT:
// Code sent state, show the verification field, the
Toast.makeText(activity,"Code sent state",Toast.LENGTH_SHORT).show();
break;
case STATE_VERIFY_FAILED:
// Verification has failed, show all options
Toast.makeText(activity,"Verification has failed",Toast.LENGTH_SHORT).show();
break;
case STATE_VERIFY_SUCCESS:
// Verification has succeeded, proceed to firebase sign in
Toast.makeText(activity,"Verification has succeeded",Toast.LENGTH_SHORT).show();
// Set the verification text based on the credential
if (cred != null) {
if (cred.getSmsCode() != null) {
//mVerificationField.setText(cred.getSmsCode());
} else {
Toast.makeText(activity,"Invalid verification code.",Toast.LENGTH_SHORT).show();
}
}
break;
case STATE_SIGNIN_FAILED:
// No-op, handled by sign-in check
Toast.makeText(activity,"Sign in failed",Toast.LENGTH_SHORT).show();
break;
case STATE_SIGNIN_SUCCESS:
// Np-op, handled by sign-in check
Toast.makeText(activity,"Sign in sucesssss!!!!",Toast.LENGTH_SHORT).show();
break;
}
if (user == null) {
// Signed out
} else {
// Signed in
}
}
public boolean validatePhoneNumber(EditText mPhoneNumberField) {
String phoneNumber = mPhoneNumberField.getText().toString();
if (TextUtils.isEmpty(phoneNumber) || phoneNumber.length()>10 || phoneNumber.length()<9) {
Toast.makeText(activity,"Invalid phone number.",Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
public PhoneAuthProvider.OnVerificationStateChangedCallbacks getmCallbacks() {
return mCallbacks;
}
public PhoneAuthProvider.ForceResendingToken getmResendToken() {
return mResendToken;
}
public FirebaseAuth getmAuth() {
return mAuth;
}
public String getVerificationCode() {
return verificationCode;
}
public void setVerificationCode(String verificationCode) {
this.verificationCode = verificationCode;
}}
在您的活动中,初始化Firebase auth和监听器
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
} else {
Log.d(TAG, "onAuthStateChanged:signed_out");
}
// ...
}
};
//init all auth process
phoneAutenticationService = new PhoneAutenticationService(this,mAuth);
@Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
getActivity().registerReceiver(smsBroadcastReceiver, filter);// define e broadcast receiver to intercept a sms verification code
}
@Override
public void onStop() {
super.onStop();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);sms code
}
getActivity().unregisterReceiver(smsBroadcastReceiver);
}最后调用firebase方法进行身份验证。
public void startAuthenticationByPhone(){
if (!validatePhoneNumber(phoneInput)) {
return;
}
startPhoneNumberVerification(phoneInput.getText().toString());
}......https://stackoverflow.com/questions/36694791
复制相似问题