Skip to content

Commit

Permalink
feat(auth): Access to FIRAuthErrorUserInfoUpdatedCredentialKey with A…
Browse files Browse the repository at this point in the history
…pple Sign In (#4359)

* Access to FIRAuthErrorUserInfoUpdatedCredentialKey with Apple Sign In
* Updates type definition
  • Loading branch information
henrik-d authored Oct 7, 2020
1 parent 0a80692 commit 5851bd0
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
31 changes: 30 additions & 1 deletion packages/auth/ios/RNFBAuth/RNFBAuthModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@

static __strong NSMutableDictionary *authStateHandlers;
static __strong NSMutableDictionary *idTokenHandlers;
// Used for caching credentials between method calls.
static __strong NSMutableDictionary<NSString *, FIRAuthCredential *> *credentials;

@implementation RNFBAuthModule
#pragma mark -
Expand All @@ -67,6 +69,7 @@ - (id)init {
dispatch_once(&onceToken, ^{
authStateHandlers = [[NSMutableDictionary alloc] init];
idTokenHandlers = [[NSMutableDictionary alloc] init];
credentials = [[NSMutableDictionary alloc] init];
});
return self;
}
Expand All @@ -88,6 +91,8 @@ - (void)invalidate {
[[FIRAuth authWithApp:firebaseApp] removeIDTokenDidChangeListener:[idTokenHandlers valueForKey:key]];
}
[idTokenHandlers removeAllObjects];

[credentials removeAllObjects];
}

#pragma mark -
Expand Down Expand Up @@ -922,7 +927,10 @@ - (void)invalidate {
- (FIRAuthCredential *)getCredentialForProvider:(NSString *)provider token:(NSString *)authToken secret:(NSString *)authTokenSecret {
FIRAuthCredential *credential;

if ([provider compare:@"twitter.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
// First check if we cached an authToken
if (credentials[authToken] != nil && ![credentials[authToken] isEqual:[NSNull null]]) {
credential = credentials[authToken];
} else if ([provider compare:@"twitter.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
credential = [FIRTwitterAuthProvider credentialWithToken:authToken secret:authTokenSecret];
} else if ([provider compare:@"facebook.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
credential = [FIRFacebookAuthProvider credentialWithAccessToken:authToken];
Expand Down Expand Up @@ -979,6 +987,7 @@ - (void)promiseRejectAuthException:(RCTPromiseRejectBlock)reject error:(NSError
@"code": [jsError valueForKey:@"code"],
@"message": [jsError valueForKey:@"message"],
@"nativeErrorMessage": [jsError valueForKey:@"nativeErrorMessage"],
@"authCredential": [jsError valueForKey:@"authCredential"],
}];
}

Expand Down Expand Up @@ -1042,10 +1051,17 @@ - (NSDictionary *)getJSError:(NSError *)error {
default:break;
}

NSDictionary *authCredentialDict = nil;
if ([error userInfo][FIRAuthErrorUserInfoUpdatedCredentialKey] != nil) {
FIRAuthCredential *authCredential = [error userInfo][FIRAuthErrorUserInfoUpdatedCredentialKey];
authCredentialDict = [self authCredentialToDict:authCredential];
}

return @{
@"code": code,
@"message": message,
@"nativeErrorMessage": nativeErrorMessage,
@"authCredential" : authCredentialDict != nil ? (id) authCredentialDict : [NSNull null],
};
}

Expand Down Expand Up @@ -1183,6 +1199,19 @@ - (NSDictionary *)firebaseUserToDict:(FIRUser *)user {
};
}

- (NSDictionary*) authCredentialToDict:(FIRAuthCredential *)authCredential {
NSString *authCredentialHash = [NSString stringWithFormat:@"%@", @([authCredential hash])];

// Temporarily store the non-serializable credential for later
credentials[authCredentialHash] = authCredential;

return @{
keyProviderId: authCredential.provider,
@"token": authCredentialHash,
@"secret": [NSNull null],
};
}

- (FIRActionCodeSettings *)buildActionCodeSettings:(NSDictionary *)actionCodeSettings {
FIRActionCodeSettings *settings = [[FIRActionCodeSettings alloc] init];

Expand Down
11 changes: 11 additions & 0 deletions packages/auth/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ export namespace FirebaseAuthTypes {
import FirebaseModule = ReactNativeFirebase.FirebaseModule;
import NativeFirebaseError = ReactNativeFirebase.NativeFirebaseError;

export interface NativeFirebaseAuthError extends NativeFirebaseError {
userInfo: {
/**
* When trying to sign in or link with an AuthCredential which was already associated with an account,
* you might receive an updated credential (depending of provider) which you can use to recover from the error.
*/
authCredential: AuthCredential | null;
};
}

/**
* Interface that represents the credentials returned by an auth provider. Implementations specify the details
* about each auth provider's credential requirements.
Expand Down Expand Up @@ -980,6 +990,7 @@ export namespace FirebaseAuthTypes {
* @error auth/wrong-password Thrown if the password used in a auth.EmailAuthProvider.credential is not correct or when the user associated with the email does not have a password.
* @error auth/invalid-verification-code Thrown if the credential is a auth.PhoneAuthProvider.credential and the verification code of the credential is not valid.
* @error auth/invalid-verification-id Thrown if the credential is a auth.PhoneAuthProvider.credential and the verification ID of the credential is not valid.
* @throws on iOS {@link auth.NativeFirebaseAuthError}, on Android {@link auth.NativeFirebaseError}
* @param credential A created {@link auth.AuthCredential}.
*/
linkWithCredential(credential: AuthCredential): Promise<UserCredential>;
Expand Down

1 comment on commit 5851bd0

@vercel
Copy link

@vercel vercel bot commented on 5851bd0 Oct 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.