- 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:
parent
50d176427f
commit
2509e7484d
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user