[android] Phone auth implementation
This commit is contained in:
parent
93079c2f01
commit
81b631f111
|
@ -561,6 +561,108 @@ class RNFirebaseAuth extends ReactContextBaseJavaModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* signInWithPhoneNumber
|
||||||
|
*
|
||||||
|
* @param appName
|
||||||
|
* @param phoneNumber
|
||||||
|
*/
|
||||||
|
@ReactMethod
|
||||||
|
public void signInWithPhoneNumber(String appName, final String phoneNumber, final Promise promise) {
|
||||||
|
Log.d(TAG, "signInWithPhoneNumber");
|
||||||
|
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
|
||||||
|
final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp);
|
||||||
|
|
||||||
|
// Reset the verification Id
|
||||||
|
mVerificationId = null;
|
||||||
|
|
||||||
|
PhoneAuthProvider.getInstance(firebaseAuth).verifyPhoneNumber(phoneNumber, 60, TimeUnit.SECONDS,
|
||||||
|
mReactContext.getCurrentActivity(), new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
|
||||||
|
private boolean promiseResolved = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVerificationCompleted(final PhoneAuthCredential phoneAuthCredential) {
|
||||||
|
// User has been automatically verified, log them in
|
||||||
|
firebaseAuth.signInWithCredential(phoneAuthCredential)
|
||||||
|
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(@NonNull Task<AuthResult> task) {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
// onAuthStateChanged will pick up the user change
|
||||||
|
Log.d(TAG, "signInWithPhoneNumber:autoVerified:signInWithCredential:onComplete:success");
|
||||||
|
// To ensure that there is no hanging promise, we resolve it with a null verificationId
|
||||||
|
// as calling ConfirmationResult.confirm(code) is invalid in this case anyway
|
||||||
|
if (!promiseResolved) {
|
||||||
|
WritableMap verificationMap = Arguments.createMap();
|
||||||
|
verificationMap.putNull("verificationId");
|
||||||
|
promise.resolve(verificationMap);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// With phone auth, the credential will only every be rejected if the user
|
||||||
|
// account linked to the phone number has been disabled
|
||||||
|
Exception exception = task.getException();
|
||||||
|
Log.e(TAG, "signInWithPhoneNumber:autoVerified:signInWithCredential:onComplete:failure", exception);
|
||||||
|
if (promiseResolved) {
|
||||||
|
// In the scenario where an SMS code has been sent, we have no way to report
|
||||||
|
// back to the front-end that as the promise has already been used
|
||||||
|
} else {
|
||||||
|
promiseRejectAuthException(promise, exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVerificationFailed(FirebaseException e) {
|
||||||
|
// This callback is invoked in an invalid request for verification is made,
|
||||||
|
// e.g. phone number format is incorrect, or the SMS quota for the project
|
||||||
|
// has been exceeded
|
||||||
|
Log.d(TAG, "signInWithPhoneNumber:verification:failed");
|
||||||
|
promiseRejectAuthException(promise, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
|
||||||
|
// TODO: This isn't being saved anywhere if the activity gets restarted when going to the SMS app
|
||||||
|
mVerificationId = verificationId;
|
||||||
|
WritableMap verificationMap = Arguments.createMap();
|
||||||
|
verificationMap.putString("verificationId", verificationId);
|
||||||
|
promise.resolve(verificationMap);
|
||||||
|
promiseResolved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCodeAutoRetrievalTimeOut(String verificationId) {
|
||||||
|
super.onCodeAutoRetrievalTimeOut(verificationId);
|
||||||
|
// Purposefully not doing anything with this at the moment
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void _confirmVerificationCode(String appName, final String verificationCode, final Promise promise) {
|
||||||
|
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
|
||||||
|
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp);
|
||||||
|
|
||||||
|
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, verificationCode);
|
||||||
|
|
||||||
|
firebaseAuth.signInWithCredential(credential)
|
||||||
|
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(@NonNull Task<AuthResult> task) {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
Log.d(TAG, "_confirmVerificationCode:signInWithCredential:onComplete:success");
|
||||||
|
promiseWithUser(task.getResult().getUser(), promise);
|
||||||
|
} else {
|
||||||
|
Exception exception = task.getException();
|
||||||
|
Log.e(TAG, "_confirmVerificationCode:signInWithCredential:onComplete:failure", exception);
|
||||||
|
promiseRejectAuthException(promise, exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* confirmPasswordReset
|
* confirmPasswordReset
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/**
|
||||||
|
* @url https://firebase.google.com/docs/reference/js/firebase.User
|
||||||
|
*/
|
||||||
|
export default class ConfirmationResult {
|
||||||
|
_auth: Object;
|
||||||
|
_verificationId: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param auth
|
||||||
|
* @param verificationId The phone number authentication operation's verification ID.
|
||||||
|
*/
|
||||||
|
constructor(auth: Object, verificationId: string) {
|
||||||
|
this._auth = auth;
|
||||||
|
this._verificationId = verificationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param verificationCode
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
confirm(verificationCode: string): Promise<Object> {
|
||||||
|
return this._auth._interceptUserValue(
|
||||||
|
this._auth._native._confirmVerificationCode(verificationCode)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
get verificationId(): String | null {
|
||||||
|
return _verificationId;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
import User from './user';
|
import User from './user';
|
||||||
import ModuleBase from './../../utils/ModuleBase';
|
import ModuleBase from './../../utils/ModuleBase';
|
||||||
|
import ConfirmationResult from './ConfirmationResult';
|
||||||
|
|
||||||
// providers
|
// providers
|
||||||
import EmailAuthProvider from './providers/Email';
|
import EmailAuthProvider from './providers/Email';
|
||||||
|
@ -8,6 +9,7 @@ import GoogleAuthProvider from './providers/Google';
|
||||||
import GithubAuthProvider from './providers/Github';
|
import GithubAuthProvider from './providers/Github';
|
||||||
import TwitterAuthProvider from './providers/Twitter';
|
import TwitterAuthProvider from './providers/Twitter';
|
||||||
import FacebookAuthProvider from './providers/Facebook';
|
import FacebookAuthProvider from './providers/Facebook';
|
||||||
|
import PhoneAuthProvider from './providers/Phone';
|
||||||
|
|
||||||
export default class Auth extends ModuleBase {
|
export default class Auth extends ModuleBase {
|
||||||
static _NAMESPACE = 'auth';
|
static _NAMESPACE = 'auth';
|
||||||
|
@ -146,6 +148,16 @@ export default class Auth extends ModuleBase {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronously signs in using a phone number.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
signInWithPhoneNumber(phoneNumber: string): Promise<Object> {
|
||||||
|
return this._native.signInWithPhoneNumber(phoneNumber).then((result) => {
|
||||||
|
return new ConfirmationResult(this, result.verificationId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send reset password instructions via email
|
* Send reset password instructions via email
|
||||||
* @param {string} email The email to send password reset instructions
|
* @param {string} email The email to send password reset instructions
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
export default {
|
||||||
|
credential(verificationId, code) {
|
||||||
|
return {
|
||||||
|
token: verificationId,
|
||||||
|
secret: code,
|
||||||
|
provider: 'phone',
|
||||||
|
providerId: 'phone',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
Loading…
Reference in New Issue