From 0914a9341ce3ef0d765fd78fde3fbeb8f295d0c3 Mon Sep 17 00:00:00 2001 From: Salakar Date: Tue, 14 Mar 2017 19:04:16 +0000 Subject: [PATCH] [ios,android] WIP - moving auth to promises & fixing ios <-> android discrepancies --- .../firebase/auth/RNFirebaseAuth.java | 185 +++++---- ios/RNFirebase/RNFirebaseAuth.m | 362 ++++++++++-------- lib/modules/auth/user.js | 17 +- 3 files changed, 335 insertions(+), 229 deletions(-) diff --git a/android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuth.java b/android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuth.java index 46c587b6..9ff09449 100644 --- a/android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuth.java +++ b/android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuth.java @@ -66,7 +66,9 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule { return TAG; } - + /** + * Add a new auth state listener - if one doesn't exist already + */ @ReactMethod public void addAuthStateListener() { if (mAuthListener == null) { @@ -179,36 +181,109 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule { }); } - + /** + * signInWithEmailAndPassword + * + * @param email + * @param password + * @param promise + */ @ReactMethod - public void signInWithEmail(final String email, final String password, final Callback callback) { - + public void signInWithEmailAndPassword(final String email, final String password, final Promise promise) { + Log.d(TAG, "signInWithEmailAndPassword"); mAuth.signInWithEmailAndPassword(email, password) - .addOnCompleteListener(new OnCompleteListener() { + .addOnSuccessListener(new OnSuccessListener() { @Override - public void onComplete(@NonNull Task task) { - try { - if (task.isSuccessful()) { - userCallback(task.getResult().getUser(), callback); - } else { - userErrorCallback(task, callback); - } - } catch (Exception ex) { - userExceptionCallback(ex, callback); - } + public void onSuccess(AuthResult authResult) { + Log.d(TAG, "signInWithEmailAndPassword:onComplete:success"); + promiseWithUser(authResult.getUser(), promise); + } + }) + .addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception exception) { + WritableMap error = authExceptionToMap(exception); + Log.e(TAG, "signInWithEmailAndPassword:onComplete:failure", exception); + promise.reject(error.getString("code"), error.getString("message"), exception); + } + }); + } + + + /** + * signInWithCustomToken + * + * @param token + * @param promise + */ + @ReactMethod + public void signInWithCustomToken(final String token, final Promise promise) { + Log.d(TAG, "signInWithCustomToken"); + mAuth.signInWithCustomToken(token) + .addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(AuthResult authResult) { + Log.d(TAG, "signInWithCustomToken:onComplete:success"); + promiseWithUser(authResult.getUser(), promise); + } + }) + .addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception exception) { + WritableMap error = authExceptionToMap(exception); + Log.e(TAG, "signInWithCustomToken:onComplete:failure", exception); + promise.reject(error.getString("code"), error.getString("message"), exception); } }); } @ReactMethod - public void signInWithProvider(final String provider, final String authToken, final String authSecret, final Callback callback) { - if (provider.equals("facebook")) { - this.facebookLogin(authToken, callback); - } else if (provider.equals("google")) { - this.googleLogin(authToken, callback); - } else - // TODO - Utils.todoNote(TAG, "signInWithProvider", callback); + public void delete(final Promise promise) { + FirebaseUser user = mAuth.getCurrentUser(); + Log.d(TAG, "delete"); + if (user != null) { + user.delete() + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + Log.d(TAG, "delete:onComplete:success"); + promiseNoUser(promise, false); + } else { + Exception exception = task.getException(); + WritableMap error = authExceptionToMap(exception); + Log.e(TAG, "delete:onComplete:failure", exception); + promise.reject(error.getString("code"), error.getString("message"), exception); + } + } + }); + } else { + Log.e(TAG, "signInWithCustomToken:onComplete:failure:noCurrentUser"); + promiseNoUser(promise, true); + } + } + + + /** + * signInWithCredential + * TODO + * + * @param provider + * @param authToken + * @param authSecret + * @param promise + */ + @ReactMethod + public void signInWithCredential(final String provider, final String authToken, final String authSecret, final Promise promise) { + switch (provider) { + case "facebook": + //facebookLogin(authToken, callback); + break; + case "google": + //googleLogin(authToken, callback); + default: + promise.reject("auth/invalid_provider", "The provider specified is invalid."); + } } @ReactMethod @@ -248,26 +323,6 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule { Utils.todoNote(TAG, "linkWithProvider", callback); } - @ReactMethod - public void signInWithCustomToken(final String customToken, final Callback callback) { - mAuth.signInWithCustomToken(customToken) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@NonNull Task task) { - Log.d(TAG, "signInWithCustomToken:onComplete:" + task.isSuccessful()); - try { - if (task.isSuccessful()) { - userCallback(task.getResult().getUser(), callback); - } else { - userErrorCallback(task, callback); - } - } catch (Exception ex) { - userExceptionCallback(ex, callback); - } - } - }); - } - @ReactMethod public void reauthenticate(final String provider, final String authToken, final String authSecret, final Callback callback) { // TODO: @@ -350,35 +405,6 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule { }); } - @ReactMethod - public void delete(final Callback callback) { - FirebaseUser user = mAuth.getCurrentUser(); - if (user != null) { - user.delete() - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@NonNull Task task) { - try { - if (task.isSuccessful()) { - Log.d(TAG, "User account deleted"); - WritableMap resp = Arguments.createMap(); - resp.putString("status", "complete"); - resp.putString("msg", "User account deleted"); - callback.invoke(null, resp); - } else { - userErrorCallback(task, callback); - } - } catch (Exception ex) { - userExceptionCallback(ex, callback); - } - } - }); - } else { - callbackNoUser(callback, true); - } - } - - @ReactMethod public void sendEmailVerification(final Callback callback) { FirebaseUser user = mAuth.getCurrentUser(); @@ -638,17 +664,28 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule { 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); + userMap.putBoolean("isAnonymous", user.isAnonymous()); + + if (email != null) { + userMap.putString("email", email); + } else { + userMap.putNull("email"); + } if (name != null) { - userMap.putString("name", name); + userMap.putString("displayName", name); + } else { + userMap.putNull("displayName"); } if (photoUrl != null) { userMap.putString("photoURL", photoUrl.toString()); + } else { + userMap.putNull("photoURL"); } return userMap; diff --git a/ios/RNFirebase/RNFirebaseAuth.m b/ios/RNFirebase/RNFirebaseAuth.m index d8e4971b..8f15b232 100644 --- a/ios/RNFirebase/RNFirebaseAuth.m +++ b/ios/RNFirebase/RNFirebaseAuth.m @@ -8,40 +8,119 @@ typedef void (^UserWithTokenResponse)(NSDictionary *, NSError *); RCT_EXPORT_MODULE(RNFirebaseAuth); -RCT_EXPORT_METHOD(signInAnonymously: - (RCTResponseSenderBlock) callBack) -{ - @try { - [[FIRAuth auth] signInAnonymouslyWithCompletion - :^(FIRUser *user, NSError *error) { - if (!user) { - NSDictionary *evt = @{ - @"eventName": AUTH_ANONYMOUS_ERROR_EVENT, - @"msg": [error localizedDescription] - }; - - - [self sendJSEvent:AUTH_CHANGED_EVENT - props: evt]; - - callBack(@[evt]); - } else { - [self userCallback:callBack user:user]; - } - }]; - } @catch(NSException *ex) { - NSDictionary *eventError = @{ - @"eventName": AUTH_ANONYMOUS_ERROR_EVENT, - @"msg": ex.reason - }; - - [self sendJSEvent:AUTH_ERROR_EVENT - props:eventError]; - NSLog(@"An exception occurred: %@", ex); - callBack(@[eventError]); +/** + signOut + + @param RCTPromiseResolveBlock resolve + @param RCTPromiseRejectBlock reject + @return + */ +RCT_EXPORT_METHOD(signOut:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject) { + FIRUser *user = [FIRAuth auth].currentUser; + + if (user) { + NSError *error; + [[FIRAuth auth] signOut:&error]; + if (!error) [self promiseNoUser:resolve rejecter:reject isError:NO]; + // TODO authExceptionToDict + else reject(@"auth/unknown", @"An unknown error has occurred.", error); + } else { + [self promiseNoUser:resolve rejecter:reject isError:YES]; } } + +/** + signInAnonymously + + @param RCTPromiseResolveBlock resolve + @param RCTPromiseRejectBlock reject + @return + */ +RCT_EXPORT_METHOD(signInAnonymously:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject) { + [[FIRAuth auth] signInAnonymouslyWithCompletion:^(FIRUser *user, NSError *error) { + if (error) { + // TODO authExceptionToDict + reject(@"auth/todo", [error localizedDescription], error); + } else { + [self promiseWithUser:resolve rejecter:reject user:user]; + } + }]; + +} + +/** + signInWithEmailAndPassword + + @param NSString NSString email + @param NSString NSString password + @param RCTPromiseResolveBlock resolve + @param RCTPromiseRejectBlock reject + @return return + */ +RCT_EXPORT_METHOD(signInWithEmailAndPassword:(NSString *)email pass:(NSString *)password resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject) { + [[FIRAuth auth] signInWithEmail:email password:password completion:^(FIRUser *user, NSError *error) { + if (error) { + // TODO authExceptionToDict + reject(@"auth/todo", [error localizedDescription], error); + } else { + [self promiseWithUser:resolve rejecter:reject user:user]; + } + }]; +} + +/** + createUserWithEmailAndPassword + + @param NSString NSString email + @param NSString NSString password + @param RCTPromiseResolveBlock resolve + @param RCTPromiseRejectBlock reject + @return return + */ +RCT_EXPORT_METHOD(createUserWithEmailAndPassword:(NSString *)email pass:(NSString *)password resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject) { + [[FIRAuth auth] createUserWithEmail:email password:password completion:^(FIRUser *user, NSError *error) { + if (error) { + // TODO authExceptionToDict + reject(@"auth/todo", [error localizedDescription], error); + } else { + [self promiseWithUser:resolve rejecter:reject user:user]; + } + }]; +} + +/** + deleteUser + + @param RCTPromiseResolveBlock resolve + @param RCTPromiseRejectBlock reject + @return return + */ +RCT_EXPORT_METHOD(delete:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject) { + FIRUser *user = [FIRAuth auth].currentUser; + + if (user) { + [user deleteWithCompletion:^(NSError *_Nullable error) { + if (error) { + // TODO authExceptionToDict + reject(@"auth/unknown", @"An unknown error has occurred.", error); + } else { + [self promiseNoUser:resolve rejecter:reject isError:NO]; + } + }]; + } else { + [self promiseNoUser:resolve rejecter:reject isError:YES]; + } +} + + + + +// TODO ------------------------------------------------------- CLEAN UP -------------------------- +// TODO ------------------------------------------------------- CLEAN UP -------------------------- +// TODO ------------------------------------------------------- CLEAN UP -------------------------- +// TODO ------------------------------------------------------- CLEAN UP -------------------------- + RCT_EXPORT_METHOD(signInWithCustomToken: (NSString *)customToken callback:(RCTResponseSenderBlock) callback) @@ -49,7 +128,7 @@ RCT_EXPORT_METHOD(signInWithCustomToken: [[FIRAuth auth] signInWithCustomToken:customToken completion:^(FIRUser *user, NSError *error) { - + if (user != nil) { [self userCallback:callback user:user]; } else { @@ -73,7 +152,7 @@ RCT_EXPORT_METHOD(signInWithProvider: }; return callback(@[err]); } - + @try { [[FIRAuth auth] signInWithCredential:credential completion:^(FIRUser *user, NSError *error) { @@ -92,24 +171,7 @@ RCT_EXPORT_METHOD(signInWithProvider: }]; } @catch (NSException *exception) { [RNFirebaseErrors handleException:exception - withCallback:callback]; - } -} - -RCT_EXPORT_METHOD(signOut:(RCTResponseSenderBlock)callback) -{ - NSError *error; - [[FIRAuth auth] signOut:&error]; - if (!error) { - // Sign-out succeeded - callback(@[[NSNull null], @YES]); - } else { - NSDictionary *err = @{ - @"error": @"Signout error", - @"name": @([error code]), - @"description": [error description] - }; - callback(@[err]); + withCallback:callback]; } } @@ -117,9 +179,8 @@ RCT_EXPORT_METHOD(addAuthStateListener) { self->listening = true; self->authListenerHandle = - [[FIRAuth auth] addAuthStateDidChangeListener:^(FIRAuth *_Nonnull auth, - FIRUser *_Nullable user) { - + [[FIRAuth auth] addAuthStateDidChangeListener:^(FIRAuth *_Nonnull auth, FIRUser *_Nullable user) { + if (user != nil) { // User is signed in. [self userPropsFromFIRUserWithToken:user @@ -168,7 +229,7 @@ RCT_EXPORT_METHOD(removeAuthStateListener:(RCTResponseSenderBlock)callback) RCT_EXPORT_METHOD(getCurrentUser:(RCTResponseSenderBlock)callback) { FIRUser *user = [FIRAuth auth].currentUser; - + if (user != nil) { [self userCallback:callback user:user]; } else { @@ -180,48 +241,11 @@ RCT_EXPORT_METHOD(getCurrentUser:(RCTResponseSenderBlock)callback) } } -RCT_EXPORT_METHOD(createUserWithEmail:(NSString *)email - pass:(NSString *)password - callback:(RCTResponseSenderBlock) callback) -{ - [[FIRAuth auth] - createUserWithEmail:email - password:password - completion:^(FIRUser *_Nullable user, - NSError *_Nullable error) { - if (user != nil) { - [self userCallback:callback user:user]; - } else { - NSDictionary *err = @{ - @"error": @"createUserWithEmailError", - @"name": @([error code]), - @"description": [error localizedDescription] - }; - callback(@[err]); - } - }]; -} - -RCT_EXPORT_METHOD(signInWithEmail:(NSString *)email - pass:(NSString *)password - callback:(RCTResponseSenderBlock) callback) -{ - [[FIRAuth auth] signInWithEmail:email - password:password - completion:^(FIRUser *user, NSError *error) { - if (user != nil) { - [self userCallback:callback user:user]; - } else { - [self userErrorCallback:callback error:error user:user msg:@"signinError"]; - } - }]; -} - RCT_EXPORT_METHOD(updateUserEmail:(NSString *)email callback:(RCTResponseSenderBlock) callback) { FIRUser *user = [FIRAuth auth].currentUser; - + if (user) { [user updateEmail:email completion:^(NSError *_Nullable error) { if (error) { @@ -240,9 +264,9 @@ RCT_EXPORT_METHOD(updateUserEmail:(NSString *)email RCT_EXPORT_METHOD(updateUserPassword:(NSString *)newPassword callback:(RCTResponseSenderBlock) callback) { - + FIRUser *user = [FIRAuth auth].currentUser; - + if (user) { [user updatePassword:newPassword completion:^(NSError *_Nullable error) { if (error) { @@ -261,7 +285,7 @@ RCT_EXPORT_METHOD(updateUserPassword:(NSString *)newPassword RCT_EXPORT_METHOD(sendPasswordResetWithEmail:(NSString *)email callback:(RCTResponseSenderBlock) callback) { - + [[FIRAuth auth] sendPasswordResetWithEmail:email completion:^(NSError *_Nullable error) { if (error) { @@ -280,27 +304,10 @@ RCT_EXPORT_METHOD(sendPasswordResetWithEmail:(NSString *)email }]; } -RCT_EXPORT_METHOD(deleteUser:(RCTResponseSenderBlock) callback) -{ - FIRUser *user = [FIRAuth auth].currentUser; - - if (user) { - [user deleteWithCompletion:^(NSError *_Nullable error) { - if (error) { - [self userErrorCallback:callback error:error user:user msg:@"deleteUserError"]; - } else { - callback(@[[NSNull null], @{@"result": @(true)}]); - } - }]; - } else { - [self noUserCallback:callback isError:true]; - } -} - RCT_EXPORT_METHOD(getToken:(RCTResponseSenderBlock) callback) { FIRUser *user = [FIRAuth auth].currentUser; - + if (user) { [user getTokenWithCompletion:^(NSString *token, NSError *_Nullable error) { if (error) { @@ -317,7 +324,7 @@ RCT_EXPORT_METHOD(getToken:(RCTResponseSenderBlock) callback) RCT_EXPORT_METHOD(getTokenWithCompletion:(RCTResponseSenderBlock) callback) { FIRUser *user = [FIRAuth auth].currentUser; - + if (user) { [user getTokenWithCompletion:^(NSString *token , NSError *_Nullable error) { if (error) { @@ -346,9 +353,9 @@ RCT_EXPORT_METHOD(reauthenticateWithCredentialForProvider: }; return callback(@[err]); } - + FIRUser *user = [FIRAuth auth].currentUser; - + [user reauthenticateWithCredential:credential completion:^(NSError *_Nullable error) { if (error) { [self userErrorCallback:callback error:error user:user msg:@"reauthenticateWithCredentialForProviderError"]; @@ -363,10 +370,10 @@ RCT_EXPORT_METHOD(updateUserProfile:(NSDictionary *)userProps callback:(RCTResponseSenderBlock) callback) { FIRUser *user = [FIRAuth auth].currentUser; - + if (user) { FIRUserProfileChangeRequest *changeRequest = [user profileChangeRequest]; - + NSMutableArray *allKeys = [[userProps allKeys] mutableCopy]; for (NSString *key in allKeys) { // i.e. changeRequest.displayName = userProps[displayName]; @@ -398,44 +405,21 @@ RCT_EXPORT_METHOD(updateUserProfile:(NSDictionary *)userProps } } -- (NSDictionary *) userPropsFromFIRUser:(FIRUser *) user -{ - NSMutableDictionary *userProps = [@{ - @"uid": user.uid, - @"email": user.email ? user.email : @"", - @"emailVerified": @(user.emailVerified), - @"anonymous": @(user.anonymous), - @"displayName": user.displayName ? user.displayName : @"", - @"refreshToken": user.refreshToken, - @"providerID": user.providerID - } mutableCopy]; - - if ([user valueForKey:@"photoURL"] != nil) { - [userProps setValue: [NSString stringWithFormat:@"%@", user.photoURL] - forKey:@"photoURL"]; - } - - return userProps; -} - - (void) userPropsFromFIRUserWithToken:(FIRUser *) user andCallback:(UserWithTokenResponse) callback { - NSMutableDictionary *userProps = [[self userPropsFromFIRUser:user] mutableCopy]; + NSMutableDictionary *userProps = [[self firebaseUserToDict:user] mutableCopy]; [user getTokenWithCompletion:^(NSString * _Nullable token, NSError * _Nullable error) { if (error != nil) { return callback(nil, error); } - + [userProps setValue:token forKey:@"idToken"]; callback(userProps, nil); }]; } -- (FIRAuthCredential *)getCredentialForProvider:(NSString *)provider - token:(NSString *)authToken - secret:(NSString *)authTokenSecret -{ +- (FIRAuthCredential *)getCredentialForProvider:(NSString *)provider token:(NSString *)authToken secret:(NSString *)authTokenSecret { FIRAuthCredential *credential; if ([provider compare:@"twitter" options:NSCaseInsensitiveSearch] == NSOrderedSame) { credential = [FIRTwitterAuthProvider credentialWithToken:authToken @@ -470,11 +454,6 @@ RCT_EXPORT_METHOD(updateUserProfile:(NSDictionary *)userProps } } -- (void) userCallback:(RCTResponseSenderBlock) callback - user:(FIRUser *) user { - NSDictionary *userProps = [self userPropsFromFIRUser:user]; - callback(@[[NSNull null], userProps]); -} - (void) noUserCallback:(RCTResponseSenderBlock) callback isError:(Boolean) isError { @@ -483,7 +462,7 @@ RCT_EXPORT_METHOD(updateUserProfile:(NSDictionary *)userProps @"error": @"Unhandled provider" }; return callback(@[err]); - + } return callback(@[[NSNull null], [NSNull null]]); } @@ -494,10 +473,87 @@ RCT_EXPORT_METHOD(updateUserProfile:(NSDictionary *)userProps msg:(NSString *) msg { // An error happened. NSDictionary *err = [RNFirebaseErrors handleFirebaseError:msg - error:error - withUser:user]; + error:error + withUser:user]; callback(@[err]); } +- (void) userCallback:(RCTResponseSenderBlock) callback user:(FIRUser *) user { + NSDictionary *userProps = [self firebaseUserToDict:user]; + callback(@[[NSNull null], userProps]); +} + +// END ------------------------------------------------------- CLEAN UP -^ ----------------------- +// END ------------------------------------------------------- CLEAN UP -------------------------- +// END ------------------------------------------------------- CLEAN UP -------------------------- +// END ------------------------------------------------------- CLEAN UP -------------------------- + + +- (NSDictionary *) authExceptionToDict:(NSError *) error { + // TODO + // NSDictionary *evt = @{ @"eventName": AUTH_ANONYMOUS_ERROR_EVENT, + // @"msg": [error localizedDescription] }; +} + + + + +/** + Resolve or reject a promise based on isError value + + @param resolve RCTPromiseResolveBlock + @param reject RCTPromiseRejectBlock + @param isError BOOL + */ +- (void) promiseNoUser:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject isError:(BOOL) isError { + if (isError) { + reject(@"auth/no_current_user", @"No user currently signed in.", nil); + } else { + resolve([NSNull null]); + } +} + +/** + Resolve or reject a promise based on FIRUser value existance + + @param resolve RCTPromiseResolveBlock + @param reject RCTPromiseRejectBlock + @param user FIRUser + */ +- (void) promiseWithUser:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject user:(FIRUser *) user { + if (user) { + NSDictionary *userDict = [self firebaseUserToDict:user]; + resolve(userDict); + } else { + [self promiseNoUser:resolve rejecter:reject isError:YES]; + } + +} + +/** + Converts a FIRUser instance into a dictionary to send via RNBridge + + @param user FIRUser + @return NSDictionary + */ +- (NSDictionary *) firebaseUserToDict:(FIRUser *) user { + NSMutableDictionary *userDict = [ + @{ @"uid": user.uid, + @"email": user.email ? user.email : [NSNull null], + @"emailVerified": @(user.emailVerified), + @"isAnonymous": @(user.anonymous), + @"displayName": user.displayName ? user.displayName : [NSNull null], + @"refreshToken": user.refreshToken, + @"providerId": [user.providerID lowercaseString] + } + mutableCopy + ]; + + if ([user valueForKey:@"photoURL"] != nil) { + [userDict setValue: [NSString stringWithFormat:@"%@", user.photoURL] forKey:@"photoURL"]; + } + + return userDict; +} @end diff --git a/lib/modules/auth/user.js b/lib/modules/auth/user.js index 3c3ac2dc..40d64dbc 100644 --- a/lib/modules/auth/user.js +++ b/lib/modules/auth/user.js @@ -51,6 +51,18 @@ export default class User { return this._user[prop]; } + /** + * Returns a user property or false if does not exist + * @param prop + * @returns {*} + * @private + */ + _valueOrFalse(prop) { + if (!this._user) return false; + if (!Object.hasOwnProperty.call(this._user, prop)) return false; + return this._user[prop]; + } + /** * PROPERTIES */ @@ -68,7 +80,7 @@ export default class User { } get isAnonymous(): Boolean { - return !this._valueOrNull('email') && this._valueOrNull('providerId') === 'firebase'; + return this._valueOrFalse('isAnonymous'); } get photoURL(): String|null { @@ -89,6 +101,7 @@ export default class User { */ toJSON() { + return Object.assign({}, this._user); return { uid: this.uid, email: this.email, @@ -105,7 +118,7 @@ export default class User { * @return {Promise} */ delete(): Promise { - return promisify('delete', FirebaseAuth, 'auth/')(); + return FirebaseAuth.delete(); } /**