[auth] Implemented fetchProvidersForEmail

This commit is contained in:
Elliot Hesp 2017-05-25 14:45:03 +01:00
parent c609539747
commit 45f8f4076d
4 changed files with 130 additions and 8 deletions

View File

@ -25,7 +25,9 @@ import com.google.android.gms.tasks.Task;
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.GithubAuthProvider; import com.google.firebase.auth.GithubAuthProvider;
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;
import com.google.firebase.auth.UserProfileChangeRequest; import com.google.firebase.auth.UserProfileChangeRequest;
@ -633,6 +635,40 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
} }
} }
/**
* fetchProvidersForEmail
*
* @param promise
*/
@ReactMethod
public void fetchProvidersForEmail(final String email, final Promise promise) {
Log.d(TAG, "fetchProvidersForEmail");
mAuth.fetchProvidersForEmail(email)
.addOnCompleteListener(new OnCompleteListener<ProviderQueryResult>() {
@Override
public void onComplete(@NonNull Task<ProviderQueryResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "fetchProvidersForEmail:onComplete:success");
List<String> providers = task.getResult().getProviders();
WritableArray array = Arguments.createArray();
if (providers != null) {
for(String provider : providers) {
array.pushString(provider);
}
}
promise.resolve(array);
} else {
Exception exception = task.getException();
Log.d(TAG, "fetchProvidersForEmail:onComplete:failure", exception);
promiseRejectAuthException(promise, exception);
}
}
});
}
/* ------------------ /* ------------------
* INTERNAL HELPERS * INTERNAL HELPERS
* ---------------- */ * ---------------- */
@ -645,7 +681,7 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
*/ */
private void promiseNoUser(Promise promise, Boolean isError) { private void promiseNoUser(Promise promise, Boolean isError) {
if (isError) { if (isError) {
promise.reject("auth/no_current_user", "No user currently signed in."); promise.reject("auth/no-current-user", "No user currently signed in.");
} else { } else {
promise.resolve(null); promise.resolve(null);
} }
@ -675,6 +711,7 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
private void promiseRejectAuthException(Promise promise, Exception exception) { private void promiseRejectAuthException(Promise promise, Exception exception) {
String code = "UNKNOWN"; String code = "UNKNOWN";
String message = exception.getMessage(); String message = exception.getMessage();
String invalidEmail = "The email address is badly formatted.";
try { try {
FirebaseAuthException authException = (FirebaseAuthException) exception; FirebaseAuthException authException = (FirebaseAuthException) exception;
@ -695,7 +732,7 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
message = "The supplied auth credential is malformed or has expired."; message = "The supplied auth credential is malformed or has expired.";
break; break;
case "INVALID_EMAIL": case "INVALID_EMAIL":
message = "The email address is badly formatted."; message = invalidEmail;
break; break;
case "WRONG_PASSWORD": case "WRONG_PASSWORD":
message = "The password is invalid or the user does not have a password."; message = "The password is invalid or the user does not have a password.";
@ -737,6 +774,11 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
} }
} }
if (code.equals("UNKNOWN") && exception instanceof FirebaseAuthInvalidCredentialsException) {
code = "INVALID_EMAIL";
message = invalidEmail;
}
code = "auth/" + code.toLowerCase().replace("error_", "").replace('_', '-'); code = "auth/" + code.toLowerCase().replace("error_", "").replace('_', '-');
promise.reject(code, message, exception); promise.reject(code, message, exception);
} }

View File

@ -433,6 +433,27 @@ RCT_EXPORT_METHOD(reauthenticate:(NSString *)provider authToken:(NSString *)auth
} }
} }
/**
fetchProvidersForEmail
@param NSString email
@param RCTPromiseResolveBlock resolve
@param RCTPromiseRejectBlock reject
@return
*/
RCT_EXPORT_METHOD(fetchProvidersForEmail:(NSString *)email resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject) {
[[FIRAuth auth] fetchProvidersForEmail:email completion:^(NSArray<NSString *> *_Nullable providers, NSError *_Nullable error) {
if (error) {
[self promiseRejectAuthException:reject error:error];
} else if (!providers) {
NSMutableArray *emptyResponse = [[NSMutableArray alloc] init];
resolve(emptyResponse);
} else {
resolve(providers);
}
}];
}
/** /**
getCredentialForProvider getCredentialForProvider
@ -472,7 +493,7 @@ RCT_EXPORT_METHOD(reauthenticate:(NSString *)provider authToken:(NSString *)auth
*/ */
- (void) promiseNoUser:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject isError:(BOOL) isError { - (void) promiseNoUser:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject isError:(BOOL) isError {
if (isError) { if (isError) {
reject(@"auth/no_current_user", @"No user currently signed in.", nil); reject(@"auth/no-current-user", @"No user currently signed in.", nil);
} else { } else {
resolve([NSNull null]); resolve([NSNull null]);
} }

View File

@ -156,6 +156,14 @@ export default class Auth extends Base {
return this._interceptUserValue(FirebaseAuth.getCurrentUser()); return this._interceptUserValue(FirebaseAuth.getCurrentUser());
} }
/**
* Returns a list of authentication providers that can be used to sign in a given user (identified by its main email address).
* @return {Promise}
*/
fetchProvidersForEmail(email: string): Promise<Object> {
return FirebaseAuth.fetchProvidersForEmail(email);
}
/** /**
* Get the currently signed in user * Get the currently signed in user
* @return {Promise} * @return {Promise}

View File

@ -49,7 +49,7 @@ function authTests({ tryCatch, describe, it, firebase }) {
const credential = firebase.native.auth.EmailAuthProvider.credential(email, pass); const credential = firebase.native.auth.EmailAuthProvider.credential(email, pass);
return currentUser return currentUser
.link(credential) .linkWithCredential(credential)
.then((linkedUser) => { .then((linkedUser) => {
linkedUser.should.be.an.Object(); linkedUser.should.be.an.Object();
linkedUser.uid.should.be.a.String(); linkedUser.uid.should.be.a.String();
@ -84,7 +84,7 @@ function authTests({ tryCatch, describe, it, firebase }) {
const credential = firebase.native.auth.EmailAuthProvider.credential(email, pass); const credential = firebase.native.auth.EmailAuthProvider.credential(email, pass);
return currentUser return currentUser
.link(credential) .linkWithCredential(credential)
.then(() => { .then(() => {
return firebase.native.auth().signOut().then(() => { return firebase.native.auth().signOut().then(() => {
return Promise.reject(new Error('Did not error on link')); return Promise.reject(new Error('Did not error on link'));
@ -149,6 +149,7 @@ function authTests({ tryCatch, describe, it, firebase }) {
}; };
const failureCb = (error) => { const failureCb = (error) => {
console.log('ERROR', error)
error.code.should.equal('auth/wrong-password'); error.code.should.equal('auth/wrong-password');
error.message.should.equal('The password is invalid or the user does not have a password.'); error.message.should.equal('The password is invalid or the user does not have a password.');
return Promise.resolve(); return Promise.resolve();
@ -246,6 +247,56 @@ function authTests({ tryCatch, describe, it, firebase }) {
}); });
}); });
describe('Email - Providers', () => {
it('it should return password provider for an email address', () => {
return new Promise((resolve, reject) => {
const successCb = tryCatch((providers) => {
providers.should.be.a.Array();
providers.should.containEql('password');
resolve();
}, reject);
const failureCb = tryCatch(() => {
reject(new Error('Should not have an error.'));
}, reject);
return firebase.native.auth().fetchProvidersForEmail('test@test.com').then(successCb).catch(failureCb);
});
});
it('it should return an empty array for a not found email', () => {
return new Promise((resolve, reject) => {
const successCb = tryCatch((providers) => {
providers.should.be.a.Array();
providers.should.be.empty();
resolve();
}, reject);
const failureCb = tryCatch(() => {
reject(new Error('Should not have an error.'));
}, reject);
return firebase.native.auth().fetchProvidersForEmail('test@i-do-not-exist.com').then(successCb).catch(failureCb);
});
});
it('it should return an error for a bad email address', () => {
return new Promise((resolve, reject) => {
const successCb = tryCatch(() => {
reject(new Error('Should not have successfully resolved.'));
}, reject);
const failureCb = tryCatch((error) => {
error.code.should.equal('auth/invalid-email');
error.message.should.equal('The email address is badly formatted.');
resolve();
}, reject);
return firebase.native.auth().fetchProvidersForEmail('foobar').then(successCb).catch(failureCb);
});
});
});
describe('Misc', () => { describe('Misc', () => {
it('it should delete a user', () => { it('it should delete a user', () => {
const random = randomString(12, '#aA'); const random = randomString(12, '#aA');
@ -264,7 +315,7 @@ function authTests({ tryCatch, describe, it, firebase }) {
return firebase.native.auth().createUserWithEmailAndPassword(email, pass).then(successCb); return firebase.native.auth().createUserWithEmailAndPassword(email, pass).then(successCb);
}); });
it('it should return a token via getToken', () => { it('it should return a token via getIdToken', () => {
const random = randomString(12, '#aA'); const random = randomString(12, '#aA');
const email = `${random}@${random}.com`; const email = `${random}@${random}.com`;
const pass = random; const pass = random;
@ -276,7 +327,7 @@ function authTests({ tryCatch, describe, it, firebase }) {
newUser.isAnonymous.should.equal(false); newUser.isAnonymous.should.equal(false);
newUser.providerId.should.equal('firebase'); newUser.providerId.should.equal('firebase');
return newUser.getToken().then((token) => { return newUser.getIdToken().then((token) => {
token.should.be.a.String(); token.should.be.a.String();
token.length.should.be.greaterThan(24); token.length.should.be.greaterThan(24);
return firebase.native.auth().currentUser.delete(); return firebase.native.auth().currentUser.delete();
@ -297,7 +348,7 @@ function authTests({ tryCatch, describe, it, firebase }) {
}, reject); }, reject);
const failureCb = tryCatch((error) => { const failureCb = tryCatch((error) => {
error.code.should.equal('auth/no_current_user'); error.code.should.equal('auth/no-current-user');
error.message.should.equal('No user currently signed in.'); error.message.should.equal('No user currently signed in.');
resolve(); resolve();
}, reject); }, reject);