[auth][js][android] remove EE based phone auth implementation
This commit is contained in:
parent
48c74ff1d7
commit
93079c2f01
|
@ -6,7 +6,6 @@ import android.support.annotation.NonNull;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -26,14 +25,11 @@ import com.google.android.gms.tasks.OnSuccessListener;
|
||||||
import com.google.android.gms.tasks.Task;
|
import com.google.android.gms.tasks.Task;
|
||||||
|
|
||||||
import com.google.firebase.FirebaseApp;
|
import com.google.firebase.FirebaseApp;
|
||||||
import com.google.firebase.FirebaseException;
|
|
||||||
import com.google.firebase.auth.ActionCodeResult;
|
import com.google.firebase.auth.ActionCodeResult;
|
||||||
import com.google.firebase.auth.AuthCredential;
|
import com.google.firebase.auth.AuthCredential;
|
||||||
import com.google.firebase.auth.AuthResult;
|
import com.google.firebase.auth.AuthResult;
|
||||||
import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException;
|
import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException;
|
||||||
import com.google.firebase.auth.GithubAuthProvider;
|
import com.google.firebase.auth.GithubAuthProvider;
|
||||||
import com.google.firebase.auth.PhoneAuthCredential;
|
|
||||||
import com.google.firebase.auth.PhoneAuthProvider;
|
|
||||||
import com.google.firebase.auth.ProviderQueryResult;
|
import com.google.firebase.auth.ProviderQueryResult;
|
||||||
import com.google.firebase.auth.TwitterAuthProvider;
|
import com.google.firebase.auth.TwitterAuthProvider;
|
||||||
import com.google.firebase.auth.UserInfo;
|
import com.google.firebase.auth.UserInfo;
|
||||||
|
@ -565,127 +561,6 @@ class RNFirebaseAuth extends ReactContextBaseJavaModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* signInWithPhoneNumber
|
|
||||||
*
|
|
||||||
* @param appName
|
|
||||||
* @param phoneNumber
|
|
||||||
* @param phoneAuthRequestKey
|
|
||||||
*/
|
|
||||||
@ReactMethod
|
|
||||||
public void signInWithPhoneNumber(final String appName, final String phoneNumber, final String phoneAuthRequestKey) {
|
|
||||||
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() {
|
|
||||||
@Override
|
|
||||||
public void onVerificationCompleted(final PhoneAuthCredential phoneAuthCredential) {
|
|
||||||
// User has been automatically verified, log them in
|
|
||||||
firebaseAuth.signInWithCredential(phoneAuthCredential)
|
|
||||||
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess(AuthResult authResult) {
|
|
||||||
Log.d(TAG, "signInWithPhoneNumber:autoVerified:success");
|
|
||||||
WritableMap event = Arguments.createMap();
|
|
||||||
WritableMap user = firebaseUserToMap(authResult.getUser());
|
|
||||||
event.putMap("user", user);
|
|
||||||
event.putString("type", "user");
|
|
||||||
event.putString("appName", appName);
|
|
||||||
event.putString("smsCode", phoneAuthCredential.getSmsCode());
|
|
||||||
event.putString("phoneAuthRequestKey", phoneAuthRequestKey);
|
|
||||||
Utils.sendEvent(mReactContext, "phone_auth_event", event);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.addOnFailureListener(new OnFailureListener() {
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull Exception exception) {
|
|
||||||
Log.e(TAG, "signInWithPhoneNumber:autoVerified:failure", exception);
|
|
||||||
WritableMap event = Arguments.createMap();
|
|
||||||
WritableMap error = getJSError(exception);
|
|
||||||
event.putMap("error", error);
|
|
||||||
event.putString("type", "error");
|
|
||||||
event.putString("appName", appName);
|
|
||||||
event.putString("phoneAuthRequestKey", phoneAuthRequestKey);
|
|
||||||
Utils.sendEvent(mReactContext, "phone_auth_event", event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onVerificationFailed(FirebaseException e) {
|
|
||||||
Log.d(TAG, "signInWithPhoneNumber:verification:failed");
|
|
||||||
WritableMap event = Arguments.createMap();
|
|
||||||
WritableMap error = getJSError(e);
|
|
||||||
event.putMap("error", error);
|
|
||||||
event.putString("type", "error");
|
|
||||||
event.putString("appName", appName);
|
|
||||||
event.putString("phoneAuthRequestKey", phoneAuthRequestKey);
|
|
||||||
Utils.sendEvent(mReactContext, "phone_auth_event", event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
|
|
||||||
WritableMap verificationMap = Arguments.createMap();
|
|
||||||
verificationMap.putString("appName", appName);
|
|
||||||
verificationMap.putString("type", "confirm");
|
|
||||||
verificationMap.putString("verificationId", verificationId);
|
|
||||||
verificationMap.putString("phoneAuthRequestKey", phoneAuthRequestKey);
|
|
||||||
Utils.sendEvent(mReactContext, "phone_auth_event", verificationMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCodeAutoRetrievalTimeOut(String verificationId) {
|
|
||||||
super.onCodeAutoRetrievalTimeOut(verificationId);
|
|
||||||
// Purposefully not doing anything with this at the moment
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@ReactMethod
|
|
||||||
public void _confirmVerificationCode(final String appName, final String phoneAuthRequestKey, String verificationId, String verificationCode, final Promise promise) {
|
|
||||||
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
|
|
||||||
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp);
|
|
||||||
|
|
||||||
// Log.d(TAG, "_confirmVerificationCode:verificationId: " + verificationId);
|
|
||||||
// Log.d(TAG, "_confirmVerificationCode:verificationCode: " + verificationCode);
|
|
||||||
|
|
||||||
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, 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");
|
|
||||||
WritableMap event = Arguments.createMap();
|
|
||||||
WritableMap user = firebaseUserToMap(task.getResult().getUser());
|
|
||||||
event.putMap("user", user);
|
|
||||||
event.putString("type", "user");
|
|
||||||
event.putString("appName", appName);
|
|
||||||
event.putString("phoneAuthRequestKey", phoneAuthRequestKey);
|
|
||||||
Utils.sendEvent(mReactContext, "phone_auth_event", event);
|
|
||||||
promiseWithUser(task.getResult().getUser(), promise);
|
|
||||||
} else {
|
|
||||||
Exception exception = task.getException();
|
|
||||||
Log.e(TAG, "_confirmVerificationCode:signInWithCredential:onComplete:failure", exception);
|
|
||||||
WritableMap event = Arguments.createMap();
|
|
||||||
WritableMap error = getJSError(exception);
|
|
||||||
event.putMap("error", error);
|
|
||||||
event.putString("type", "error");
|
|
||||||
event.putString("appName", appName);
|
|
||||||
event.putString("phoneAuthRequestKey", phoneAuthRequestKey);
|
|
||||||
Utils.sendEvent(mReactContext, "phone_auth_event", event);
|
|
||||||
promiseRejectAuthException(promise, exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* confirmPasswordReset
|
* confirmPasswordReset
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
/**
|
|
||||||
* @url https://firebase.google.com/docs/reference/js/firebase.User
|
|
||||||
*/
|
|
||||||
export default class ConfirmationResult {
|
|
||||||
_auth: Object;
|
|
||||||
_verificationId: string;
|
|
||||||
_phoneAuthRequestKey: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param auth
|
|
||||||
* @param verificationId The phone number authentication operation's verification ID.
|
|
||||||
* @param phoneAuthRequestKey
|
|
||||||
*/
|
|
||||||
constructor(auth: Object, verificationId: string, phoneAuthRequestKey: string) {
|
|
||||||
this._auth = auth;
|
|
||||||
this._verificationId = verificationId;
|
|
||||||
this._phoneAuthRequestKey = phoneAuthRequestKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param verificationCode
|
|
||||||
* @return {*}
|
|
||||||
*/
|
|
||||||
confirm(verificationCode: string): Promise<Object> {
|
|
||||||
return this._auth._native._confirmVerificationCode(
|
|
||||||
this._phoneAuthRequestKey,
|
|
||||||
this._verificationId,
|
|
||||||
verificationCode,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get verificationId(): String | null {
|
|
||||||
return _verificationId;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +1,9 @@
|
||||||
// @flow
|
// @flow
|
||||||
import User from './user';
|
import User from './user';
|
||||||
import INTERNALS from './../../internals';
|
|
||||||
import ModuleBase from './../../utils/ModuleBase';
|
import ModuleBase from './../../utils/ModuleBase';
|
||||||
import { nativeToJSError, generatePushID, isFunction } from './../../utils';
|
|
||||||
import ConfirmationResult from './ConfirmationResult';
|
|
||||||
|
|
||||||
// providers
|
// providers
|
||||||
import EmailAuthProvider from './providers/Email';
|
import EmailAuthProvider from './providers/Email';
|
||||||
import PhoneAuthProvider from './providers/Phone';
|
|
||||||
import GoogleAuthProvider from './providers/Google';
|
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';
|
||||||
|
@ -33,48 +29,9 @@ export default class Auth extends ModuleBase {
|
||||||
this._onAuthStateChanged.bind(this),
|
this._onAuthStateChanged.bind(this),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.addListener(
|
|
||||||
// sub to phone auth native event - this can
|
|
||||||
// be either a code sent confirmation result
|
|
||||||
// event, a successful signIn event or an
|
|
||||||
// error event
|
|
||||||
this._getAppEventName('phone_auth_event'),
|
|
||||||
this._onPhoneAuthEvent.bind(this),
|
|
||||||
);
|
|
||||||
|
|
||||||
this._native.addAuthStateListener();
|
this._native.addAuthStateListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles an incoming phone auth event and emits to the internal once listeners.
|
|
||||||
* @param event
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_onPhoneAuthEvent(event) {
|
|
||||||
const { type, phoneAuthRequestKey } = event;
|
|
||||||
|
|
||||||
if (type === 'confirm') {
|
|
||||||
return this.emit(
|
|
||||||
`phone:auth:${phoneAuthRequestKey}:confirm`,
|
|
||||||
new ConfirmationResult(this, event.verificationId, phoneAuthRequestKey),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'user') {
|
|
||||||
return this.emit(
|
|
||||||
`phone:auth:${phoneAuthRequestKey}:user`,
|
|
||||||
this._onAuthStateChanged({ authenticated: true, user: event.user }, false),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'error') {
|
|
||||||
const { code, message } = event.error;
|
|
||||||
return this.emit(`phone:auth:${phoneAuthRequestKey}:error`, nativeToJSError(code, message));
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('Internal RNFirebase Error: Invalid phone auth event received.');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal auth changed listener
|
* Internal auth changed listener
|
||||||
* @param auth
|
* @param auth
|
||||||
|
@ -189,53 +146,6 @@ export default class Auth extends ModuleBase {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param phoneNumber
|
|
||||||
* @return Object
|
|
||||||
*/
|
|
||||||
signInWithPhoneNumber(phoneNumber: string): Promise<Object> {
|
|
||||||
const phoneAuthRequestKey = generatePushID();
|
|
||||||
|
|
||||||
return {
|
|
||||||
onCodeSent: (cb) => {
|
|
||||||
if (!isFunction(cb)) {
|
|
||||||
throw new Error(INTERNALS.STRINGS.ERROR_MISSING_CB('onCodeSent'));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.once(`phone:auth:${phoneAuthRequestKey}:confirm`, cb);
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
// start auth flow
|
|
||||||
this._native.signInWithPhoneNumber(
|
|
||||||
phoneNumber,
|
|
||||||
phoneAuthRequestKey,
|
|
||||||
);
|
|
||||||
|
|
||||||
let hadEvent = false;
|
|
||||||
const successEvent = `phone:auth:${phoneAuthRequestKey}:user`;
|
|
||||||
const errorEvent = `phone:auth:${phoneAuthRequestKey}:error`;
|
|
||||||
|
|
||||||
this.once(successEvent, (user) => {
|
|
||||||
if (!hadEvent) {
|
|
||||||
hadEvent = true;
|
|
||||||
this.removeListener(errorEvent, reject);
|
|
||||||
resolve(user);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.once(errorEvent, (error) => {
|
|
||||||
if (!hadEvent) {
|
|
||||||
hadEvent = true;
|
|
||||||
this.removeListener(successEvent, resolve);
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
export default {
|
|
||||||
credential(verificationId, code) {
|
|
||||||
return {
|
|
||||||
token: verificationId,
|
|
||||||
secret: code,
|
|
||||||
provider: 'phone',
|
|
||||||
providerId: 'phone',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -23,11 +23,8 @@ const NATIVE_MODULE_EVENTS = {
|
||||||
],
|
],
|
||||||
Auth: [
|
Auth: [
|
||||||
'onAuthStateChanged',
|
'onAuthStateChanged',
|
||||||
'phone_auth_event',
|
|
||||||
],
|
],
|
||||||
Database: [
|
Database: [
|
||||||
// 'database_on_event',
|
|
||||||
// 'database_cancel_event',
|
|
||||||
'database_transaction_event',
|
'database_transaction_event',
|
||||||
// 'database_server_offset', // TODO
|
// 'database_server_offset', // TODO
|
||||||
],
|
],
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,108 +0,0 @@
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { View, Button, Text, TextInput, Image } from 'react-native';
|
|
||||||
|
|
||||||
import fb from './firebase';
|
|
||||||
const firebase = fb.native;
|
|
||||||
|
|
||||||
if (firebase.auth().currentUser) firebase.auth().signOut();
|
|
||||||
const successImageUri = 'https://cdn.pixabay.com/photo/2015/06/09/16/12/icon-803718_1280.png';
|
|
||||||
|
|
||||||
export default class PhoneAuthTest extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
user: null,
|
|
||||||
message: '',
|
|
||||||
codeInput: '',
|
|
||||||
phoneNumber: '+447',
|
|
||||||
confirmResult: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
signIn = () => {
|
|
||||||
const { phoneNumber } = this.state;
|
|
||||||
this.setState({ message: 'Sending code ...' });
|
|
||||||
|
|
||||||
firebase.auth()
|
|
||||||
.signInWithPhoneNumber(phoneNumber)
|
|
||||||
.onCodeSent(confirmResult => this.setState({ confirmResult, message: 'Code has been sent!' }))
|
|
||||||
.then(user => this.setState({ user: user.toJSON() }))
|
|
||||||
.catch(console.error);
|
|
||||||
};
|
|
||||||
|
|
||||||
confirmCode = () => {
|
|
||||||
const { codeInput, confirmResult } = this.state;
|
|
||||||
|
|
||||||
if (confirmResult && codeInput.length) {
|
|
||||||
confirmResult.confirm(codeInput)
|
|
||||||
.then(() => this.setState({ message: 'Code Confirmed!' }))
|
|
||||||
.catch(error => this.setState({ message: `Code Confirm Error: ${error.message}` }));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { message, user, codeInput, confirmResult, phoneNumber } = this.state;
|
|
||||||
return (
|
|
||||||
<View style={{ flex: 1 }}>
|
|
||||||
{!user && !confirmResult ? (
|
|
||||||
<View style={{ padding: 25 }}>
|
|
||||||
<Text>Enter phone number:</Text>
|
|
||||||
<TextInput
|
|
||||||
autoFocus
|
|
||||||
style={{ height: 40, marginTop: 15, marginBottom: 15 }}
|
|
||||||
onChangeText={value => this.setState({ phoneNumber: value })}
|
|
||||||
placeholder={'Phone number ... '}
|
|
||||||
value={phoneNumber}
|
|
||||||
/>
|
|
||||||
<Button title="Sign In" color="green" onPress={this.signIn} />
|
|
||||||
</View>
|
|
||||||
) : null}
|
|
||||||
{message.length ? (
|
|
||||||
<Text style={{ padding: 5, backgroundColor: '#000', color: '#fff' }}>{message}</Text>) : null}
|
|
||||||
{!user && confirmResult ? (
|
|
||||||
<View style={{ marginTop: 25, padding: 25 }}>
|
|
||||||
<Text>Enter verification code below:</Text>
|
|
||||||
<TextInput
|
|
||||||
autoFocus
|
|
||||||
style={{ height: 40, marginTop: 15, marginBottom: 15 }}
|
|
||||||
onChangeText={value => this.setState({ codeInput: value })}
|
|
||||||
placeholder={'Code ... '}
|
|
||||||
value={codeInput}
|
|
||||||
/>
|
|
||||||
<Button title="Confirm Code" color="#841584" onPress={this.confirmCode} />
|
|
||||||
</View>
|
|
||||||
) : null}
|
|
||||||
{ user ? (
|
|
||||||
<View
|
|
||||||
style={{
|
|
||||||
padding: 15,
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
backgroundColor: '#77dd77',
|
|
||||||
flex: 1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Image source={{ uri: successImageUri }} style={{ width: 100, height: 100, marginBottom: 25 }} />
|
|
||||||
<Text style={{ fontSize: 25 }}>Signed In!</Text>
|
|
||||||
<Text>{JSON.stringify(user)}</Text>
|
|
||||||
<Button
|
|
||||||
title="Logout"
|
|
||||||
color="#841584"
|
|
||||||
onPress={() => {
|
|
||||||
firebase.auth().signOut().then(() => {
|
|
||||||
this.setState({
|
|
||||||
user: null,
|
|
||||||
message: '',
|
|
||||||
codeInput: '',
|
|
||||||
phoneNumber: '+44',
|
|
||||||
confirmResult: null,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
) : null}
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
import { Platform } from 'react-native';
|
||||||
|
|
||||||
import firebase from 'firebase';
|
import firebase from 'firebase';
|
||||||
import RNfirebase from './../firebase/firebase';
|
import RNfirebase from './../firebase/firebase';
|
||||||
import { Platform } from 'react-native';
|
|
||||||
|
|
||||||
import DatabaseContents from './tests/support/DatabaseContents';
|
import DatabaseContents from './tests/support/DatabaseContents';
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue