added auth method result interceptor - grab user objects and shim into currentUser

This commit is contained in:
Salakar 2017-03-13 20:02:44 +00:00
parent 7710dd94a7
commit 15167a4f81
2 changed files with 183 additions and 101 deletions

View File

@ -68,7 +68,7 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
@ReactMethod @ReactMethod
public void createAuthStateListener() { public void addAuthStateListener() {
if (mAuthListener == null) { if (mAuthListener == null) {
mAuthListener = new FirebaseAuth.AuthStateListener() { mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override @Override
@ -79,7 +79,7 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
if (user != null) { if (user != null) {
// TODO move to helper // TODO move to helper
WritableMap userMap = getUserMap(user); WritableMap userMap = firebaseUserToMap(user);
msgMap.putBoolean("authenticated", true); msgMap.putBoolean("authenticated", true);
msgMap.putMap("user", userMap); msgMap.putMap("user", userMap);
@ -94,38 +94,88 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
} }
} }
/**
* Removes the current auth state listener
* @param callback
*/
@ReactMethod @ReactMethod
public void unlistenForAuth(final Callback callback) { public void removeAuthStateListener(final Callback callback) {
if (mAuthListener != null) { if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener); mAuth.removeAuthStateListener(mAuthListener);
// TODO move to helper // TODO move to helper
WritableMap resp = Arguments.createMap(); WritableMap resp = Arguments.createMap();
resp.putString("status", "complete"); resp.putString("status", "complete");
callback.invoke(null, resp); callback.invoke(null, resp);
} }
} }
/**
* signOut
* @param promise
*/
@ReactMethod @ReactMethod
public void createUserWithEmail(final String email, final String password, final Callback callback) { public void signOut(final Promise promise) {
mAuth.createUserWithEmailAndPassword(email, password) if (mAuth == null || mAuth.getCurrentUser() == null) {
.addOnCompleteListener(new OnCompleteListener<AuthResult>() { promiseNoUser(promise, true);
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
try {
if (task.isSuccessful()) {
userCallback(task.getResult().getUser(), callback);
} else { } else {
userErrorCallback(task, callback); mAuth.signOut();
promiseNoUser(promise, false);
} }
} catch (Exception ex) {
userExceptionCallback(ex, callback);
} }
/**
* signInAnonymously
* @param promise
*/
@ReactMethod
public void signInAnonymously(final Promise promise) {
Log.d(TAG, "signInAnonymously");
mAuth.signInAnonymously()
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
Log.d(TAG, "signInAnonymously:onComplete:success");
promiseWithUser(authResult.getUser(), promise);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
WritableMap error = authExceptionToMap(exception);
Log.e(TAG, "signInAnonymously:onComplete:failure", exception);
promise.reject(error.getString("code"), error.getString("message"), exception);
} }
}); });
} }
/**
* createUserWithEmailAndPassword
* @param email
* @param password
* @param promise
*/
@ReactMethod
public void createUserWithEmailAndPassword(final String email, final String password, final Promise promise) {
Log.d(TAG, "createUserWithEmailAndPassword");
mAuth.createUserWithEmailAndPassword(email, password)
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
Log.d(TAG, "createUserWithEmailAndPassword:onComplete:success");
promiseWithUser(authResult.getUser(), promise);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
WritableMap error = authExceptionToMap(exception);
Log.e(TAG, "createUserWithEmailAndPassword:onComplete:failure", exception);
promise.reject(error.getString("code"), error.getString("message"), exception);
}
});
}
@ReactMethod @ReactMethod
public void signInWithEmail(final String email, final String password, final Callback callback) { public void signInWithEmail(final String email, final String password, final Callback callback) {
@ -194,27 +244,6 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
Utils.todoNote(TAG, "linkWithProvider", callback); Utils.todoNote(TAG, "linkWithProvider", callback);
} }
@ReactMethod
public void signInAnonymously(final Promise promise) {
Log.d(TAG, "signInAnonymously");
mAuth.signInAnonymously()
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
Log.d(TAG, "signInAnonymously:onComplete:success");
promise.resolve(authResult.getUser());
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
WritableMap error = authExceptionToMap(exception);
Log.e(TAG, "signInAnonymously:onComplete:failure", exception);
promise.reject(error.getString("code"), error.getString("message"), exception);
}
});
}
@ReactMethod @ReactMethod
public void signInWithCustomToken(final String customToken, final Callback callback) { public void signInWithCustomToken(final String customToken, final Callback callback) {
mAuth.signInWithCustomToken(customToken) mAuth.signInWithCustomToken(customToken)
@ -453,15 +482,6 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
} }
} }
@ReactMethod
public void signOut(final Callback callback) {
mAuth.signOut();
WritableMap resp = Arguments.createMap();
resp.putString("status", "complete");
resp.putString("msg", "User signed out");
callback.invoke(null, resp);
}
@ReactMethod @ReactMethod
public void reloadUser(final Callback callback) { public void reloadUser(final Callback callback) {
@ -543,10 +563,53 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
* ---------------- */ * ---------------- */
/** /**
* * Resolves or rejects an auth method promise without a user (user was missing)
* @param promise
* @param isError
*/
private void promiseNoUser(Promise promise, Boolean isError) {
if (isError) {
promise.reject("auth/no_current_user", "No user currently signed in.");
} else {
promise.resolve(null);
}
}
/**
* @param user
* @param promise
*/
private void promiseWithUser(final FirebaseUser user, final Promise promise) {
if (user != null) {
user.getToken(true)
.addOnSuccessListener(new OnSuccessListener<GetTokenResult>() {
@Override
public void onSuccess(GetTokenResult getTokenResult) {
Log.d(TAG, "promiseWithUser:getToken:success");
WritableMap userMap = firebaseUserToMap(user);
userMap.putString("token", getTokenResult.getToken());
promise.resolve(userMap);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
WritableMap error = authExceptionToMap(exception);
Log.e(TAG, "promiseWithUser:getToken::failure", exception);
promise.reject(error.getString("code"), error.getString("message"), exception);
}
});
} else {
promiseNoUser(promise, true);
}
}
/**
* @param user * @param user
* @param callback * @param callback
*/ */
@Deprecated
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>() {
@ -554,7 +617,7 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
public void onComplete(@NonNull Task<GetTokenResult> task) { public void onComplete(@NonNull Task<GetTokenResult> task) {
try { try {
if (task.isSuccessful()) { if (task.isSuccessful()) {
WritableMap userMap = getUserMap(user); WritableMap userMap = firebaseUserToMap(user);
userMap.putString("token", task.getResult().getToken()); userMap.putString("token", task.getResult().getToken());
callback.invoke(null, userMap); callback.invoke(null, userMap);
} else { } else {
@ -570,8 +633,39 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
} }
} }
/**
* @param user
* @return
*/
private WritableMap firebaseUserToMap(FirebaseUser user) {
WritableMap userMap = Arguments.createMap();
final String email = user.getEmail();
final String uid = user.getUid();
final String provider = user.getProviderId();
final String name = user.getDisplayName();
final Boolean verified = user.isEmailVerified();
final Uri photoUrl = user.getPhotoUrl();
userMap.putString("email", email);
userMap.putString("uid", uid);
userMap.putString("providerId", provider);
userMap.putBoolean("emailVerified", verified);
if (name != null) {
userMap.putString("name", name);
}
if (photoUrl != null) {
userMap.putString("photoURL", photoUrl.toString());
}
return userMap;
}
/** /**
* Returns web code and message values. * Returns web code and message values.
*
* @param exception Auth exception * @param exception Auth exception
* @return WritableMap writable map with code and message string values * @return WritableMap writable map with code and message string values
*/ */
@ -647,6 +741,7 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
* *
* @param callback JS callback * @param callback JS callback
*/ */
@Deprecated
private void callbackNoUser(Callback callback, Boolean isError) { private void callbackNoUser(Callback callback, Boolean isError) {
WritableMap err = Arguments.createMap(); WritableMap err = Arguments.createMap();
err.putInt("code", NO_CURRENT_USER); err.putInt("code", NO_CURRENT_USER);
@ -671,33 +766,4 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
error.putString("message", ex.getMessage()); error.putString("message", ex.getMessage());
onFail.invoke(error); onFail.invoke(error);
} }
private WritableMap getUserMap(FirebaseUser user) {
WritableMap userMap = Arguments.createMap();
if (user != null) {
final String email = user.getEmail();
final String uid = user.getUid();
final String provider = user.getProviderId();
final String name = user.getDisplayName();
final Boolean verified = user.isEmailVerified();
final Uri photoUrl = user.getPhotoUrl();
userMap.putString("email", email);
userMap.putString("uid", uid);
userMap.putString("providerId", provider);
userMap.putBoolean("emailVerified", verified);
if (name != null) {
userMap.putString("name", name);
}
if (photoUrl != null) {
userMap.putString("photoURL", photoUrl.toString());
}
} else {
userMap.putString("msg", "no user");
}
return userMap;
}
} }

View File

@ -28,21 +28,49 @@ export default class Auth extends Base {
// 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('onAuthStateChanged', this._onAuthStateChanged.bind(this)); FirebaseAuthEvt.addListener('onAuthStateChanged', this._onAuthStateChanged.bind(this));
FirebaseAuth.createAuthStateListener(); FirebaseAuth.addAuthStateListener();
} }
/** /**
* Internal auth changed listener * Internal auth changed listener
* @param auth * @param auth
* @param emit
* @private * @private
*/ */
_onAuthStateChanged(auth: AuthResultType) { _onAuthStateChanged(auth: AuthResultType, emit: Boolean = true) {
this._authResult = auth; this._authResult = auth;
this.authenticated = auth ? auth.authenticated || false : false; this.authenticated = auth ? auth.authenticated || false : false;
if (auth && auth.user && !this._user) this._user = new User(this, auth); if (auth && auth.user && !this._user) this._user = new User(this, auth);
else if ((!auth || !auth.user) && this._user) this._user = null; else if ((!auth || !auth.user) && this._user) this._user = null;
else if (this._user) this._user._updateValues(auth); else if (this._user) this._user._updateValues(auth);
this.emit('onAuthStateChanged', this._authResult.user || null); if (emit) this.emit('onAuthStateChanged', this._authResult.user || null);
return auth ? this._user : null;
}
/**
* Remove auth change listener
* @param listener
*/
_offAuthStateChanged(listener: Function) {
this.log.info('Removing onAuthStateChanged listener');
this.removeListener('onAuthStateChanged', listener);
}
/**
* Intercept all user actions and send their results to
* auth state change before resolving
* @param promise
* @returns {Promise.<TResult>|*}
* @private
*/
_interceptUserValue(promise) {
return promise.then((result) => {
if (!result) return this._onAuthStateChanged(null, false);
if (result.user) return this._onAuthStateChanged(result, false);
if (result.uid) return this._onAuthStateChanged({ user: result }, false);
return result;
});
} }
/* /*
@ -61,21 +89,19 @@ export default class Auth extends Base {
} }
/** /**
* Remove auth change listener * Sign the current user out
* @param listener * @return {Promise}
*/ */
_offAuthStateChanged(listener: Function) { signOut(): Promise<null> {
this.log.info('Removing onAuthStateChanged listener'); return this._interceptUserValue(FirebaseAuth.signOut());
this.removeListener('onAuthStateChanged', listener);
} }
/** /**
* Sign a user in anonymously * Sign a user in anonymously
* @return {Promise} A promise resolved upon completion * @return {Promise} A promise resolved upon completion
*/ */
signInAnonymously(): Promise<Object> { signInAnonymously(): Promise<Object> {
return FirebaseAuth.signInAnonymously(); return this._interceptUserValue(FirebaseAuth.signInAnonymously());
} }
/** /**
@ -85,8 +111,7 @@ export default class Auth extends Base {
* @return {Promise} A promise indicating the completion * @return {Promise} A promise indicating the completion
*/ */
createUserWithEmailAndPassword(email: string, password: string): Promise<Object> { createUserWithEmailAndPassword(email: string, password: string): Promise<Object> {
this.log.info('Creating user with email and password', email); return this._interceptUserValue(FirebaseAuth.createUserWithEmailAndPassword(email, password));
return promisify('createUserWithEmail', FirebaseAuth, 'auth/')(email, password);
} }
/** /**
@ -201,15 +226,6 @@ export default class Auth extends Base {
return promisify('getToken', FirebaseAuth, 'auth/')(); return promisify('getToken', FirebaseAuth, 'auth/')();
} }
/**
* Sign the current user out
* @return {Promise}
*/
signOut(): Promise<Object> {
return promisify('signOut', FirebaseAuth, 'auth/')();
}
/** /**
* Get the currently signed in user * Get the currently signed in user
* @return {Promise} * @return {Promise}