2
0
mirror of synced 2025-02-23 03:28:25 +00:00

- switched signInAnonymously to use RN promises native side

- created helper to convert auth exceptions into cleaner web equivalent error codes/messages
This commit is contained in:
Salakar 2017-03-13 17:23:41 +00:00
parent 50d176427f
commit 2509e7484d
2 changed files with 133 additions and 48 deletions

View File

@ -4,11 +4,14 @@ package io.invertase.firebase.auth;
import android.util.Log; import android.util.Log;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReactMethod;
@ -18,6 +21,8 @@ import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContext;
import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
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.auth.AuthCredential; import com.google.firebase.auth.AuthCredential;
@ -61,32 +66,16 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
return TAG; return TAG;
} }
/**
* Returns a no user error.
*
* @param callback JS callback
*/
private void callbackNoUser(Callback callback, Boolean isError) {
WritableMap err = Arguments.createMap();
err.putInt("errorCode", NO_CURRENT_USER);
err.putString("errorMessage", "No current user");
if (isError) {
callback.invoke(err);
} else {
callback.invoke(null, null);
}
}
@ReactMethod @ReactMethod
public void listenForAuth() { public void createAuthStateListener() {
if (mAuthListener == null) { if (mAuthListener == null) {
mAuthListener = new FirebaseAuth.AuthStateListener() { mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override @Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser(); FirebaseUser user = firebaseAuth.getCurrentUser();
WritableMap msgMap = Arguments.createMap(); WritableMap msgMap = Arguments.createMap();
msgMap.putString("eventName", "listenForAuth"); msgMap.putString("eventName", "onAuthStateChanged");
if (user != null) { if (user != null) {
// TODO move to helper // TODO move to helper
@ -94,10 +83,10 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
msgMap.putBoolean("authenticated", true); msgMap.putBoolean("authenticated", true);
msgMap.putMap("user", userMap); msgMap.putMap("user", userMap);
Utils.sendEvent(mReactContext, "listenForAuth", msgMap); Utils.sendEvent(mReactContext, "onAuthStateChanged", msgMap);
} else { } else {
msgMap.putBoolean("authenticated", false); msgMap.putBoolean("authenticated", false);
Utils.sendEvent(mReactContext, "listenForAuth", msgMap); Utils.sendEvent(mReactContext, "onAuthStateChanged", msgMap);
} }
} }
}; };
@ -206,23 +195,22 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
} }
@ReactMethod @ReactMethod
public void signInAnonymously(final Callback callback) { public void signInAnonymously(final Promise promise) {
Log.d(TAG, "signInAnonymously:called:"); Log.d(TAG, "signInAnonymously");
mAuth.signInAnonymously() mAuth.signInAnonymously()
.addOnCompleteListener(new OnCompleteListener<AuthResult>() { .addOnSuccessListener(new OnSuccessListener<AuthResult>() {
@Override @Override
public void onComplete(@NonNull Task<AuthResult> task) { public void onSuccess(AuthResult authResult) {
Log.d(TAG, "signInAnonymously:onComplete:" + task.isSuccessful()); Log.d(TAG, "signInAnonymously:onComplete:success");
promise.resolve(authResult.getUser());
try { }
if (task.isSuccessful()) { })
userCallback(task.getResult().getUser(), callback); .addOnFailureListener(new OnFailureListener() {
} else { @Override
userErrorCallback(task, callback); public void onFailure(@NonNull Exception exception) {
} WritableMap error = authExceptionToMap(exception);
} catch (Exception ex) { Log.e(TAG, "signInAnonymously:onComplete:failure", exception);
userExceptionCallback(ex, callback); promise.reject(error.getString("code"), error.getString("message"), exception);
}
} }
}); });
} }
@ -550,7 +538,15 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
}); });
} }
// Internal helpers /* ------------------
* INTERNAL HELPERS
* ---------------- */
/**
*
* @param user
* @param callback
*/
private void userCallback(final FirebaseUser user, final Callback callback) { private void userCallback(final FirebaseUser user, final Callback callback) {
if (user != null) { if (user != null) {
user.getToken(true).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() { user.getToken(true).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
@ -574,10 +570,98 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
} }
} }
/**
* Returns web code and message values.
* @param exception Auth exception
* @return WritableMap writable map with code and message string values
*/
private WritableMap authExceptionToMap(Exception exception) {
WritableMap error = Arguments.createMap();
String code = "UNKNOWN";
String message = exception.getMessage();
Matcher matcher = Pattern.compile("\\[(.*?)\\]").matcher(message);
if (matcher.find()) {
code = matcher.group().substring(2, matcher.group().length() - 2);
switch (code) {
case "INVALID_CUSTOM_TOKEN":
message = "The custom token format is incorrect. Please check the documentation.";
break;
case "CUSTOM_TOKEN_MISMATCH":
message = "The custom token corresponds to a different audience.";
break;
case "INVALID_CREDENTIAL":
message = "The supplied auth credential is malformed or has expired.";
break;
case "INVALID_EMAIL":
message = "The email address is badly formatted.";
break;
case "WRONG_PASSWORD":
message = "The password is invalid or the user does not have a password.";
break;
case "USER_MISMATCH":
message = "The supplied credentials do not correspond to the previously signed in user.";
break;
case "REQUIRES_RECENT_LOGIN":
message = "This operation is sensitive and requires recent authentication. Log in again before retrying this request.";
break;
case "ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL":
message = "An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address.";
break;
case "EMAIL_ALREADY_IN_USE":
message = "The email address is already in use by another account.";
break;
case "CREDENTIAL_ALREADY_IN_USE":
message = "This credential is already associated with a different user account.";
break;
case "USER_USER_DISABLED":
message = "The user account has been disabled by an administrator.";
break;
case "USER_TOKEN_EXPIRED":
message = "The user\'s credential is no longer valid. The user must sign in again.";
break;
case "USER_NOT_FOUND":
message = "There is no user record corresponding to this identifier. The user may have been deleted.";
break;
case "INVALID_USER_TOKEN":
message = "The user\'s credential is no longer valid. The user must sign in again.";
break;
case "WEAK_PASSWORD":
message = "The given password is invalid.";
break;
case "OPERATION_NOT_ALLOWED":
message = "This operation is not allowed. You must enable this service in the console.";
break;
case "FOO":
break;
}
}
error.putString("code", "auth/" + code.toLowerCase());
error.putString("message", message);
return error;
}
/**
* Returns a no user error.
*
* @param callback JS callback
*/
private void callbackNoUser(Callback callback, Boolean isError) {
WritableMap err = Arguments.createMap();
err.putInt("code", NO_CURRENT_USER);
err.putString("message", "No current user");
if (isError) {
callback.invoke(err);
} else {
callback.invoke(null, null);
}
}
private void userErrorCallback(Task task, final Callback onFail) { private void userErrorCallback(Task task, final Callback onFail) {
WritableMap error = Arguments.createMap(); WritableMap error = Arguments.createMap();
error.putString("code", ((FirebaseAuthException) task.getException()).getErrorCode()); error.putString("message", ((FirebaseAuthException) task.getException()).getMessage());
error.putString("message", task.getException().getMessage());
onFail.invoke(error); onFail.invoke(error);
} }

View File

@ -27,8 +27,8 @@ export default class Auth extends Base {
// start listening straight away // start listening straight away
// generally though the initial event fired will get ignored // generally though the initial event fired will get ignored
// but this is ok as we fake it with the getCurrentUser below // but this is ok as we fake it with the getCurrentUser below
FirebaseAuthEvt.addListener('listenForAuth', this._onAuthStateChanged.bind(this)); FirebaseAuthEvt.addListener('onAuthStateChanged', this._onAuthStateChanged.bind(this));
FirebaseAuth.listenForAuth(); FirebaseAuth.createAuthStateListener();
} }
/** /**
@ -69,6 +69,15 @@ export default class Auth extends Base {
this.removeListener('onAuthStateChanged', listener); this.removeListener('onAuthStateChanged', listener);
} }
/**
* Sign a user in anonymously
* @return {Promise} A promise resolved upon completion
*/
signInAnonymously(): Promise<Object> {
return FirebaseAuth.signInAnonymously();
}
/** /**
* Create a user with the email/password functionality * Create a user with the email/password functionality
* @param {string} email The user's email * @param {string} email The user's email
@ -160,14 +169,6 @@ export default class Auth extends Base {
return promisify('reauthenticateWithCredentialForProvider', FirebaseAuth, 'auth/')(credential.provider, credential.token, credential.secret); return promisify('reauthenticateWithCredentialForProvider', FirebaseAuth, 'auth/')(credential.provider, credential.token, credential.secret);
} }
/**
* Sign a user in anonymously
* @return {Promise} A promise resolved upon completion
*/
signInAnonymously(): Promise<Object> {
return promisify('signInAnonymously', FirebaseAuth, 'auth/')();
}
/** /**
* 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