[ios][android] Authentication improvements (#1663)

* [internals][js] nativeWithArgs wrapper incorrectly wrapping NativeModule constants - should only wrap functions

* [ios][android][js][auth] ensure user login state is consistent across RN reloads + tests

* remove test focus

* [android][auth] clear all auth state and id token listeners between React Native reloads

* [ios][auth] clear all auth state and id token listeners between React Native reloads

* [ios][auth] cleanup and add new auth error codes
This commit is contained in:
Michael Diarmid
2018-11-04 04:06:40 +00:00
committed by GitHub
parent 424d1e8f60
commit 5120121797
7 changed files with 275 additions and 72 deletions

View File

@@ -45,6 +45,7 @@ import com.google.firebase.auth.UserInfo;
import com.google.firebase.auth.UserProfileChangeRequest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -63,14 +64,14 @@ class RNFirebaseAuth extends ReactContextBaseJavaModule {
private PhoneAuthProvider.ForceResendingToken mForceResendingToken;
private PhoneAuthCredential mCredential;
private ReactContext mReactContext;
private HashMap<String, FirebaseAuth.AuthStateListener> mAuthListeners = new HashMap<>();
private HashMap<String, FirebaseAuth.IdTokenListener> mIdTokenListeners = new HashMap<>();
private static HashMap<String, FirebaseAuth.AuthStateListener> mAuthListeners = new HashMap<>();
private static HashMap<String, FirebaseAuth.IdTokenListener> mIdTokenListeners = new HashMap<>();
RNFirebaseAuth(ReactApplicationContext reactContext) {
super(reactContext);
mReactContext = reactContext;
Log.d(TAG, "RNFirebaseAuth:initialized");
Log.d(TAG, "instance-created");
}
@Override
@@ -78,6 +79,46 @@ class RNFirebaseAuth extends ReactContextBaseJavaModule {
return TAG;
}
@Override
public void initialize() {
super.initialize();
Log.d(TAG, "instance-initialized");
}
@Override
public void onCatalystInstanceDestroy() {
super.onCatalystInstanceDestroy();
Log.d(TAG, "instance-destroyed");
Iterator authListenerIterator = mAuthListeners
.entrySet()
.iterator();
while (authListenerIterator.hasNext()) {
Map.Entry pair = (Map.Entry) authListenerIterator.next();
String appName = (String) pair.getKey();
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp);
FirebaseAuth.AuthStateListener mAuthListener = (FirebaseAuth.AuthStateListener) pair.getValue();
firebaseAuth.removeAuthStateListener(mAuthListener);
authListenerIterator.remove();
}
Iterator idTokenListenerIterator = mIdTokenListeners
.entrySet()
.iterator();
while (idTokenListenerIterator.hasNext()) {
Map.Entry pair = (Map.Entry) idTokenListenerIterator.next();
String appName = (String) pair.getKey();
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp);
FirebaseAuth.IdTokenListener mAuthListener = (FirebaseAuth.IdTokenListener) pair.getValue();
firebaseAuth.removeIdTokenListener(mAuthListener);
idTokenListenerIterator.remove();
}
}
/**
* Add a new auth state listener - if one doesn't exist already
*/
@@ -2007,17 +2048,25 @@ class RNFirebaseAuth extends ReactContextBaseJavaModule {
List<FirebaseApp> firebaseAppList = FirebaseApp.getApps(getReactApplicationContext());
final Map<String, Object> appLanguage = new HashMap<>();
final Map<String, Object> appUser = new HashMap<>();
for (FirebaseApp app : firebaseAppList) {
String appName = app.getName();
FirebaseApp instance = FirebaseApp.getInstance(appName);
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(instance);
FirebaseUser user = firebaseAuth.getCurrentUser();
appLanguage.put(appName, firebaseAuth.getLanguageCode());
if (user != null) {
appUser.put(appName, firebaseUserToMap(user));
}
}
constants.put("APP_LANGUAGE", appLanguage);
constants.put("APP_USER", appUser);
return constants;
}
}

View File

@@ -8,11 +8,68 @@
#import <React/RCTEventEmitter.h>
@interface RNFirebaseAuth : RCTEventEmitter <RCTBridgeModule> {};
@property NSMutableDictionary *authStateHandlers;
@property NSMutableDictionary *idTokenHandlers;
@end
extern NSString * const AuthErrorCode_toJSErrorCode[];
NSString * const AuthErrorCode_toJSErrorCode[] = {
[FIRAuthErrorCodeInvalidCustomToken] = @"auth/invalid-custom-token",
[FIRAuthErrorCodeCustomTokenMismatch] = @"auth/custom-token-mismatch",
[FIRAuthErrorCodeInvalidCredential] = @"auth/invalid-credential",
[FIRAuthErrorCodeUserDisabled] = @"auth/user-disabled",
[FIRAuthErrorCodeOperationNotAllowed] = @"auth/operation-not-allowed",
[FIRAuthErrorCodeEmailAlreadyInUse] = @"auth/email-already-in-use",
[FIRAuthErrorCodeInvalidEmail] = @"auth/invalid-email",
[FIRAuthErrorCodeWrongPassword] = @"auth/wrong-password",
[FIRAuthErrorCodeTooManyRequests] = @"auth/too-many-requests",
[FIRAuthErrorCodeUserNotFound] = @"auth/user-not-found",
[FIRAuthErrorCodeAccountExistsWithDifferentCredential] = @"auth/account-exists-with-different-credential",
[FIRAuthErrorCodeRequiresRecentLogin] = @"auth/requires-recent-login",
[FIRAuthErrorCodeProviderAlreadyLinked] = @"auth/provider-already-linked",
[FIRAuthErrorCodeNoSuchProvider] = @"auth/no-such-provider",
[FIRAuthErrorCodeInvalidUserToken] = @"auth/invalid-user-token",
[FIRAuthErrorCodeNetworkError] = @"auth/network-request-failed",
[FIRAuthErrorCodeUserTokenExpired] = @"auth/user-token-expired",
[FIRAuthErrorCodeInvalidAPIKey] = @"auth/invalid-api-key",
[FIRAuthErrorCodeUserMismatch] = @"auth/user-mismatch",
[FIRAuthErrorCodeCredentialAlreadyInUse] = @"auth/credential-already-in-use",
[FIRAuthErrorCodeWeakPassword] = @"auth/weak-password",
[FIRAuthErrorCodeAppNotAuthorized] = @"auth/app-not-authorized",
[FIRAuthErrorCodeExpiredActionCode] = @"auth/expired-action-code",
[FIRAuthErrorCodeInvalidActionCode] = @"auth/invalid-action-code",
[FIRAuthErrorCodeInvalidMessagePayload] = @"auth/invalid-message-payload",
[FIRAuthErrorCodeInvalidSender] = @"auth/invalid-sender",
[FIRAuthErrorCodeInvalidRecipientEmail] = @"auth/invalid-recipient-email",
[FIRAuthErrorCodeMissingEmail] = @"auth/invalid-email",
[FIRAuthErrorCodeMissingIosBundleID] = @"auth/missing-ios-bundle-id",
[FIRAuthErrorCodeMissingAndroidPackageName] = @"auth/missing-android-pkg-name",
[FIRAuthErrorCodeUnauthorizedDomain] = @"auth/unauthorized-domain",
[FIRAuthErrorCodeInvalidContinueURI] = @"auth/invalid-continue-uri",
[FIRAuthErrorCodeMissingContinueURI] = @"auth/missing-continue-uri",
[FIRAuthErrorCodeMissingPhoneNumber] = @"auth/missing-phone-number",
[FIRAuthErrorCodeInvalidPhoneNumber] = @"auth/invalid-phone-number",
[FIRAuthErrorCodeMissingVerificationCode] = @"auth/missing-verification-code",
[FIRAuthErrorCodeInvalidVerificationCode] = @"auth/invalid-verification-code",
[FIRAuthErrorCodeMissingVerificationID] = @"auth/missing-verification-id",
[FIRAuthErrorCodeInvalidVerificationID] = @"auth/invalid-verification-id",
[FIRAuthErrorCodeMissingAppCredential] = @"auth/missing-app-credential",
[FIRAuthErrorCodeInvalidAppCredential] = @"auth/invalid-app-credential",
[FIRAuthErrorCodeSessionExpired] = @"auth/code-expired",
[FIRAuthErrorCodeQuotaExceeded] = @"auth/quota-exceeded",
[FIRAuthErrorCodeMissingAppToken] = @"auth/missing-apns-token",
[FIRAuthErrorCodeNotificationNotForwarded] = @"auth/notification-not-forwarded",
[FIRAuthErrorCodeAppNotVerified] = @"auth/app-not-verified",
[FIRAuthErrorCodeCaptchaCheckFailed] = @"auth/captcha-check-failed",
[FIRAuthErrorCodeWebContextAlreadyPresented] = @"auth/cancelled-popup-request",
[FIRAuthErrorCodeWebContextCancelled] = @"auth/popup-closed-by-user",
[FIRAuthErrorCodeAppVerificationUserInteractionFailure] = @"auth/app-verification-user-interaction-failure",
[FIRAuthErrorCodeInvalidClientID] = @"auth/invalid-oauth-client-id",
[FIRAuthErrorCodeWebNetworkRequestFailed] = @"auth/network-request-failed",
[FIRAuthErrorCodeWebInternalError] = @"auth/internal-error",
[FIRAuthErrorCodeNullUser] = @"auth/null-user",
[FIRAuthErrorCodeKeychainError] = @"auth/keychain-error",
[FIRAuthErrorCodeInternalError] = @"auth/internal-error",
[FIRAuthErrorCodeMalformedJWT] = @"auth/malformed-jwt"
};
#else
@interface RNFirebaseAuth : NSObject
@end

View File

@@ -22,21 +22,46 @@ static NSString *const keyDisplayName = @"displayName";
static NSString *const keyPackageName = @"packageName";
static NSString *const keyMinVersion = @"minimumVersion";
static NSString *const constAppLanguage = @"APP_LANGUAGE";
static NSString *const constAppUser = @"APP_USER";
static NSString *const keyHandleCodeInApp = @"handleCodeInApp";
static NSString *const keyAdditionalUserInfo = @"additionalUserInfo";
static NSMutableDictionary *authStateHandlers;
static NSMutableDictionary *idTokenHandlers;
@implementation RNFirebaseAuth
RCT_EXPORT_MODULE();
- (id)init {
self = [super init];
if (self != nil) {
_authStateHandlers = [[NSMutableDictionary alloc] init];
_idTokenHandlers = [[NSMutableDictionary alloc] init];
}
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
authStateHandlers = [[NSMutableDictionary alloc] init];
idTokenHandlers = [[NSMutableDictionary alloc] init];
DLog(@"RNFirebaseAuth:instance-created");
});
DLog(@"RNFirebaseAuth:instance-initialized");
return self;
}
- (void)dealloc {
DLog(@"RNFirebaseAuth:instance-destroyed");
for(NSString* key in authStateHandlers) {
FIRApp *firApp = [RNFirebaseUtil getApp:key];
[[FIRAuth authWithApp:firApp] removeAuthStateDidChangeListener:[authStateHandlers valueForKey:key]];
[authStateHandlers removeObjectForKey:key];
}
for(NSString* key in idTokenHandlers) {
FIRApp *firApp = [RNFirebaseUtil getApp:key];
[[FIRAuth authWithApp:firApp] removeIDTokenDidChangeListener:[idTokenHandlers valueForKey:key]];
[idTokenHandlers removeObjectForKey:key];
}
}
/**
* addAuthStateListener
*
@@ -45,7 +70,7 @@ RCT_EXPORT_METHOD(addAuthStateListener:
(NSString *) appDisplayName) {
FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName];
if (![_authStateHandlers valueForKey:firApp.name]) {
if (![authStateHandlers valueForKey:firApp.name]) {
FIRAuthStateDidChangeListenerHandle newListenerHandle =
[[FIRAuth authWithApp:firApp] addAuthStateDidChangeListener:^(FIRAuth *_Nonnull auth, FIRUser *_Nullable user) {
if (user != nil) {
@@ -56,7 +81,7 @@ RCT_EXPORT_METHOD(addAuthStateListener:
}
}];
_authStateHandlers[firApp.name] = [NSValue valueWithNonretainedObject:newListenerHandle];
authStateHandlers[firApp.name] = [NSValue valueWithNonretainedObject:newListenerHandle];
}
}
@@ -68,9 +93,9 @@ RCT_EXPORT_METHOD(removeAuthStateListener:
(NSString *) appDisplayName) {
FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName];
if ([_authStateHandlers valueForKey:firApp.name]) {
[[FIRAuth authWithApp:firApp] removeAuthStateDidChangeListener:[_authStateHandlers valueForKey:firApp.name]];
[_authStateHandlers removeObjectForKey:firApp.name];
if ([authStateHandlers valueForKey:firApp.name]) {
[[FIRAuth authWithApp:firApp] removeAuthStateDidChangeListener:[authStateHandlers valueForKey:firApp.name]];
[authStateHandlers removeObjectForKey:firApp.name];
}
}
@@ -82,7 +107,7 @@ RCT_EXPORT_METHOD(addIdTokenListener:
(NSString *) appDisplayName) {
FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName];
if (![_idTokenHandlers valueForKey:firApp.name]) {
if (![idTokenHandlers valueForKey:firApp.name]) {
FIRIDTokenDidChangeListenerHandle newListenerHandle =
[[FIRAuth authWithApp:firApp] addIDTokenDidChangeListener:^(FIRAuth *_Nonnull auth, FIRUser *_Nullable user) {
if (user != nil) {
@@ -93,7 +118,7 @@ RCT_EXPORT_METHOD(addIdTokenListener:
}
}];
_idTokenHandlers[firApp.name] = [NSValue valueWithNonretainedObject:newListenerHandle];
idTokenHandlers[firApp.name] = [NSValue valueWithNonretainedObject:newListenerHandle];
}
}
@@ -105,9 +130,9 @@ RCT_EXPORT_METHOD(removeIdTokenListener:
(NSString *) appDisplayName) {
FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName];
if ([_idTokenHandlers valueForKey:firApp.name]) {
[[FIRAuth authWithApp:firApp] removeIDTokenDidChangeListener:[_idTokenHandlers valueForKey:firApp.name]];
[_idTokenHandlers removeObjectForKey:firApp.name];
if ([idTokenHandlers valueForKey:firApp.name]) {
[[FIRAuth authWithApp:firApp] removeIDTokenDidChangeListener:[idTokenHandlers valueForKey:firApp.name]];
[idTokenHandlers removeObjectForKey:firApp.name];
}
}
@@ -1246,90 +1271,72 @@ RCT_EXPORT_METHOD(verifyPasswordResetCode:
@param error NSError
*/
- (NSDictionary *)getJSError:(NSError *)error {
NSString *code = @"auth/unknown";
NSString *code = AuthErrorCode_toJSErrorCode[error.code];
NSString *message = [error localizedDescription];
NSString *nativeErrorMessage = [error localizedDescription];
if (code == nil) code = @"auth/unknown";
// TODO: Salakar: replace these with a AuthErrorCode_toJSErrorMessage map (like codes now does)
switch (error.code) {
case FIRAuthErrorCodeInvalidCustomToken:code = @"auth/invalid-custom-token";
case FIRAuthErrorCodeInvalidCustomToken:
message = @"The custom token format is incorrect. Please check the documentation.";
break;
case FIRAuthErrorCodeCustomTokenMismatch:code = @"auth/custom-token-mismatch";
case FIRAuthErrorCodeCustomTokenMismatch:
message = @"The custom token corresponds to a different audience.";
break;
case FIRAuthErrorCodeInvalidCredential:code = @"auth/invalid-credential";
case FIRAuthErrorCodeInvalidCredential:
message = @"The supplied auth credential is malformed or has expired.";
break;
case FIRAuthErrorCodeInvalidEmail:code = @"auth/invalid-email";
case FIRAuthErrorCodeInvalidEmail:
message = @"The email address is badly formatted.";
break;
case FIRAuthErrorCodeWrongPassword:code = @"auth/wrong-password";
case FIRAuthErrorCodeWrongPassword:
message = @"The password is invalid or the user does not have a password.";
break;
case FIRAuthErrorCodeUserMismatch:code = @"auth/user-mismatch";
case FIRAuthErrorCodeUserMismatch:
message = @"The supplied credentials do not correspond to the previously signed in user.";
break;
case FIRAuthErrorCodeRequiresRecentLogin:code = @"auth/requires-recent-login";
case FIRAuthErrorCodeRequiresRecentLogin:
message =
@"This operation is sensitive and requires recent authentication. Log in again before retrying this request.";
break;
case FIRAuthErrorCodeAccountExistsWithDifferentCredential:code = @"auth/account-exists-with-different-credential";
case FIRAuthErrorCodeAccountExistsWithDifferentCredential:
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 FIRAuthErrorCodeEmailAlreadyInUse:code = @"auth/email-already-in-use";
case FIRAuthErrorCodeEmailAlreadyInUse:
message = @"The email address is already in use by another account.";
break;
case FIRAuthErrorCodeCredentialAlreadyInUse:code = @"auth/credential-already-in-use";
case FIRAuthErrorCodeCredentialAlreadyInUse:
message = @"This credential is already associated with a different user account.";
break;
case FIRAuthErrorCodeUserDisabled:code = @"auth/user-disabled";
case FIRAuthErrorCodeUserDisabled:
message = @"The user account has been disabled by an administrator.";
break;
case FIRAuthErrorCodeUserTokenExpired:code = @"auth/user-token-expired";
case FIRAuthErrorCodeUserTokenExpired:
message = @"The user's credential is no longer valid. The user must sign in again.";
break;
case FIRAuthErrorCodeUserNotFound:code = @"auth/user-not-found";
case FIRAuthErrorCodeUserNotFound:
message = @"There is no user record corresponding to this identifier. The user may have been deleted.";
break;
case FIRAuthErrorCodeInvalidUserToken:code = @"auth/invalid-user-token";
case FIRAuthErrorCodeInvalidUserToken:
message = @"The user's credential is no longer valid. The user must sign in again.";
break;
case FIRAuthErrorCodeWeakPassword:code = @"auth/weak-password";
case FIRAuthErrorCodeWeakPassword:
message = @"The given password is invalid.";
break;
case FIRAuthErrorCodeOperationNotAllowed:code = @"auth/operation-not-allowed";
case FIRAuthErrorCodeOperationNotAllowed:
message = @"This operation is not allowed. You must enable this service in the console.";
break;
case FIRAuthErrorCodeNetworkError:code = @"auth/network-error";
case FIRAuthErrorCodeNetworkError:
message = @"A network error has occurred, please try again.";
break;
case FIRAuthErrorCodeInternalError:code = @"auth/internal-error";
case FIRAuthErrorCodeInternalError:
message = @"An internal error has occurred, please try again.";
break;
// unsure of the below codes so leaving them as the default error message
case FIRAuthErrorCodeTooManyRequests:code = @"auth/too-many-requests";
default:
break;
case FIRAuthErrorCodeProviderAlreadyLinked:code = @"auth/provider-already-linked";
break;
case FIRAuthErrorCodeNoSuchProvider:code = @"auth/no-such-provider";
break;
case FIRAuthErrorCodeInvalidAPIKey:code = @"auth/invalid-api-key";
break;
case FIRAuthErrorCodeAppNotAuthorized:code = @"auth/app-not-authorised";
break;
case FIRAuthErrorCodeExpiredActionCode:code = @"auth/expired-action-code";
break;
case FIRAuthErrorCodeInvalidMessagePayload:code = @"auth/invalid-message-payload";
break;
case FIRAuthErrorCodeInvalidSender:code = @"auth/invalid-sender";
break;
case FIRAuthErrorCodeInvalidRecipientEmail:code = @"auth/invalid-recipient-email";
break;
case FIRAuthErrorCodeKeychainError:code = @"auth/keychain-error";
break;
default:break;
}
return @{
@@ -1460,13 +1467,26 @@ RCT_EXPORT_METHOD(verifyPasswordResetCode:
NSDictionary *firApps = [FIRApp allApps];
NSMutableDictionary *constants = [NSMutableDictionary new];
NSMutableDictionary *appLanguage = [NSMutableDictionary new];
NSMutableDictionary *appUser = [NSMutableDictionary new];
for (id key in firApps) {
FIRApp *firApp = firApps[key];
appLanguage[firApp.name] = [FIRAuth authWithApp:firApp].languageCode;
NSString *appName = firApp.name;
FIRUser *user = [FIRAuth authWithApp:firApp].currentUser;
if ([appName isEqualToString:@"__FIRAPP_DEFAULT"]) {
appName = @"[DEFAULT]";
}
appLanguage[appName] = [FIRAuth authWithApp:firApp].languageCode;
if (user != nil) {
appUser[appName] = [self firebaseUserToDict: user];
}
}
constants[constAppLanguage] = appLanguage;
constants[constAppUser] = appUser;
return constants;
}

View File

@@ -62,13 +62,18 @@ export default class Auth extends ModuleBase {
hasCustomUrlSupport: false,
namespace: NAMESPACE,
});
const NativeModule = getNativeModule(this);
this._user = null;
this._settings = null;
this._authResult = false;
this._languageCode =
getNativeModule(this).APP_LANGUAGE[app._name] ||
getNativeModule(this).APP_LANGUAGE['[DEFAULT]'];
NativeModule.APP_LANGUAGE[app._name] ||
NativeModule.APP_LANGUAGE['[DEFAULT]'];
if (NativeModule.APP_USER[app._name]) {
this._setUser(NativeModule.APP_USER[app._name]);
}
SharedEventEmitter.addListener(
// sub to internal native event - this fans out to
@@ -106,8 +111,8 @@ export default class Auth extends ModuleBase {
}
);
getNativeModule(this).addAuthStateListener();
getNativeModule(this).addIdTokenListener();
NativeModule.addAuthStateListener();
NativeModule.addIdTokenListener();
}
_setUser(user: ?NativeUser): ?User {

View File

@@ -24,8 +24,12 @@ const nativeWithArgs = (
for (let i = 0, len = methods.length; i < len; i++) {
const method = methods[i];
native[method] = (...args) =>
NativeModule[method](...[...argToPrepend, ...args]);
if (typeof NativeModule[method] === 'function') {
native[method] = (...args) =>
NativeModule[method](...[...argToPrepend, ...args]);
} else {
native[method] = NativeModule[method];
}
}
return native;

View File

@@ -0,0 +1,68 @@
describe('auth()', () => {
beforeEach(async () => {
if (firebase.auth().currentUser) {
await firebase.auth().signOut();
await sleep(50);
}
});
describe('firebase.auth().currentUser', () => {
it('exists after reload', async () => {
let currentUser;
// before reload
await firebase.auth().signInAnonymously();
({ currentUser } = firebase.auth());
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
should.equal(currentUser.toJSON().email, null);
currentUser.isAnonymous.should.equal(true);
currentUser.providerId.should.equal('firebase');
currentUser.should.equal(firebase.auth().currentUser);
// RELOAD
await device.reloadReactNative();
// after reload
({ currentUser } = firebase.auth());
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
should.equal(currentUser.toJSON().email, null);
currentUser.isAnonymous.should.equal(true);
currentUser.providerId.should.equal('firebase');
currentUser.should.equal(firebase.auth().currentUser);
// test correct user is returned after signing
// in with a different user then reloading
await firebase.auth().signOut();
const email = 'test@test.com';
const pass = 'test1234';
await firebase.auth().signInWithEmailAndPassword(email, pass);
({ currentUser } = firebase.auth());
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
currentUser.toJSON().email.should.eql(email);
currentUser.isAnonymous.should.equal(false);
currentUser.providerId.should.equal('firebase');
currentUser.should.equal(firebase.auth().currentUser);
// RELOAD
await device.reloadReactNative();
// after reload
({ currentUser } = firebase.auth());
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
currentUser.toJSON().email.should.eql(email);
currentUser.isAnonymous.should.equal(false);
currentUser.providerId.should.equal('firebase');
currentUser.should.equal(firebase.auth().currentUser);
}).timeout(15000);
});
});

View File

@@ -3713,9 +3713,9 @@ jest-worker@23.2.0, jest-worker@^23.2.0:
dependencies:
merge-stream "^1.0.1"
jet@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/jet/-/jet-0.1.0.tgz#242f2b104e5626dee18f0f50cb889638ac1f6364"
jet@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/jet/-/jet-0.2.0.tgz#84b7efc4fccd7da74c33447db7264d6942051e1d"
dependencies:
chalk "^2.4.1"
error-stack-parser "^2.0.2"