Signing in users with Facebook on iOS

You can let your users authenticate with Identity Platform using their Facebook accounts by integrating Facebook Login or Facebook Limited Login into your app. This page shows you how to use Identity Platform to add Sign in with Facebook to your iOS app.

Before you begin

  1. Add Firebase to your iOS project.

  2. Include the following pods in your Podfile:

    pod 'FirebaseAuth'
    
  3. Go to the Identity Providers page in the Google Cloud console.

    Go to the Identity Providers page

  4. Click Add A Provider.

  5. Select Facebook from the list.

  6. Enter your Facebook App ID and App Secret. If you don't already have an ID and secret, you can obtain one from the Facebook for Developers page.

  7. Configure the URI listed under Configure Facebook as a valid OAuth redirect URI for your Facebook app. If you configured a custom domain in Identity Platform, update the redirect URI in your Facebook app configuration to use the custom domain instead of the default domain. For example, change https://myproject.firebaseapp.com/__/auth/handler to https://auth.myownpersonaldomain.com/__/auth/handler.

  8. Register your app's domains by clicking Add Domain under Authorized Domains. For development purposes, localhost is already enabled by default.

  9. Under Configure your application, click Setup Details. Copy the snippet into your app's code to initialize the Identity Platform client SDK.

  10. Click Save.

Implement Facebook Login

To use "classic" Facebook Login, complete the following steps. Alternatively, you can use Facebook Limited Login, as shown in the next section.

  1. Integrate Facebook Login into your app by following the developer's documentation. When you initialize the FBSDKLoginButton object, set a delegate to receive login and logout events. For example:

    Swift

    letloginButton=FBSDKLoginButton()
    loginButton.delegate=self

    Objective-C

    FBSDKLoginButton*loginButton=[[FBSDKLoginButtonalloc]init];
    loginButton.delegate=self;
    In your delegate, implement didCompleteWithResult:error:.

    Swift

    funcloginButton(_loginButton:FBSDKLoginButton!,didCompleteWithresult:FBSDKLoginManagerLoginResult!,error:Error!){
    ifleterror=error{
    print(error.localizedDescription)
    return
    }
    // ...
    }

    Objective-C

    - (void)loginButton:(FBSDKLoginButton*)loginButton
    didCompleteWithResult:(FBSDKLoginManagerLoginResult*)result
    error:(NSError*)error{
    if(error==nil){
    // ...
    }else{
    NSLog(error.localizedDescription);
    }
    }
  2. Import the Firebase module in your UIApplicationDelegate:

    Swift

    importFirebaseCore
    importFirebaseAuth
    

    Objective-C

    @importFirebaseCore;
    @importFirebaseAuth;
    
  3. Configure a FirebaseApp shared instance, typically in your app's application:didFinishLaunchingWithOptions: method:

    Swift

    // Use Firebase library to configure APIs
    FirebaseApp.configure()

    Objective-C

    // Use Firebase library to configure APIs
    [FIRAppconfigure];
  4. After a user successfully signs in, in your implementation of didCompleteWithResult:error:, get an access token for the signed-in user and exchange it for an Identity Platform credential:

    Swift

    letcredential=FacebookAuthProvider
    .credential(withAccessToken:AccessToken.current!.tokenString)

    Objective-C

    FIRAuthCredential*credential=[FIRFacebookAuthProvider
    credentialWithAccessToken:[FBSDKAccessTokencurrentAccessToken].tokenString];

Implement Facebook Limited Login

To use Facebook Limited Login instead of "classic" Facebook Login, complete the following steps.

  1. Integrate Facebook Limited Login into your app by following the developer's documentation.
  2. For every sign-in request, generate a unique random string—a "nonce"—which you will use to make sure the ID token you get was granted specifically in response to your app's authentication request. This step is important to prevent replay attacks. You can generate a cryptographically secure nonce on iOS with SecRandomCopyBytes(_:_:_), as in the following example:

    Swift

    privatefuncrandomNonceString(length:Int=32)->String{
    precondition(length > 0)
    varrandomBytes=[UInt8](repeating:0,count:length)
    leterrorCode=SecRandomCopyBytes(kSecRandomDefault,randomBytes.count,&randomBytes)
    iferrorCode!=errSecSuccess{
    fatalError(
    "Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)"
    )
    }
    letcharset:[Character]=
    Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._")
    letnonce=randomBytes.map{bytein
    // Pick a random character from the set, wrapping around if needed.
    charset[Int(byte)%charset.count]
    }
    returnString(nonce)
    }
    

    Objective-C

    // Adapted from https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce
    - (NSString*)randomNonce:(NSInteger)length{
    NSAssert(length > 0,@"Expected nonce to have positive length");
    NSString*characterSet=@"0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._";
    NSMutableString*result=[NSMutableStringstring];
    NSIntegerremainingLength=length;
    while(remainingLength > 0){
    NSMutableArray*randoms=[NSMutableArrayarrayWithCapacity:16];
    for(NSIntegeri=0;i < 16;i++){
    uint8_trandom=0;
    interrorCode=SecRandomCopyBytes(kSecRandomDefault,1,&random);
    NSAssert(errorCode==errSecSuccess,@"Unable to generate nonce: OSStatus %i",errorCode);
    [randomsaddObject:@(random)];
    }
    for(NSNumber*randominrandoms){
    if(remainingLength==0){
    break;
    }
    if(random.unsignedIntValue < characterSet.length){
    unicharcharacter=[characterSetcharacterAtIndex:random.unsignedIntValue];
    [resultappendFormat:@"%C",character];
    remainingLength--;
    }
    }
    }
    return[resultcopy];
    }
    
    You will send the SHA-256 hash of the nonce with your sign-in request, which Facebook will pass unchanged in the response. Identity Platform validates the response by hashing the original nonce and comparing it to the value passed by Facebook.

    Swift

    @available(iOS13,*)
    privatefuncsha256(_input:String)->String{
    letinputData=Data(input.utf8)
    lethashedData=SHA256.hash(data:inputData)
    lethashString=hashedData.compactMap{
    String(format:"%02x",0ドル)
    }.joined()
    returnhashString
    }
    

    Objective-C

    - (NSString*)stringBySha256HashingString:(NSString*)input{
    constchar*string=[inputUTF8String];
    unsignedcharresult[CC_SHA256_DIGEST_LENGTH];
    CC_SHA256(string,(CC_LONG)strlen(string),result);
    NSMutableString*hashed=[NSMutableStringstringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
    for(NSIntegeri=0;i < CC_SHA256_DIGEST_LENGTH;i++){
    [hashedappendFormat:@"%02x",result[i]];
    }
    returnhashed;
    }
    
  3. When you set up the FBSDKLoginButton, set a delegate to receive login and logout events, set the tracking mode to FBSDKLoginTrackingLimited, and attach a nonce. For example:

    Swift

    funcsetupLoginButton(){
    letnonce=randomNonceString()
    currentNonce=nonce
    loginButton.delegate=self
    loginButton.loginTracking=.limited
    loginButton.nonce=sha256(nonce)
    }
    

    Objective-C

    - (void)setupLoginButton{
    NSString*nonce=[selfrandomNonce:32];
    self.currentNonce=nonce;
    self.loginButton.delegate=self;
    self.loginButton.loginTracking=FBSDKLoginTrackingLimited
    self.loginButton.nonce=[selfstringBySha256HashingString:nonce];
    }
    
    In your delegate, implement didCompleteWithResult:error:.

    Swift

    funcloginButton(_loginButton:FBSDKLoginButton!,didCompleteWithresult:FBSDKLoginManagerLoginResult!,error:Error!){
    ifleterror=error{
    print(error.localizedDescription)
    return
    }
    // ...
    }
    

    Objective-C

    - (void)loginButton:(FBSDKLoginButton*)loginButton
    didCompleteWithResult:(FBSDKLoginManagerLoginResult*)result
    error:(NSError*)error{
    if(error==nil){
    // ...
    }else{
    NSLog(error.localizedDescription);
    }
    }
    
  4. Import the Firebase module in your UIApplicationDelegate:

    Swift

    importFirebase

    Objective-C

    @importFirebase;
  5. Configure a FirebaseApp shared instance, typically in your app's application:didFinishLaunchingWithOptions: method:

    Swift

    // Use Firebase library to configure APIs
    FirebaseApp.configure()

    Objective-C

    // Use Firebase library to configure APIs
    [FIRAppconfigure];
  6. After a user successfully signs in, in your implementation of didCompleteWithResult:error:, use the ID token from Facebook's response with the unhashed nonce to get an Identity Platform credential:

    Swift

    // Initialize an Identity Platform credential.
    letidTokenString=AuthenticationToken.current?.tokenString
    letnonce=currentNonce
    letcredential=OAuthProvider.credential(withProviderID:"facebook.com",
    IDToken:idTokenString,
    rawNonce:nonce)
    

    Objective-C

    // Initialize an Identity Platform credential.
    NSString*idTokenString=FBSDKAuthenticationToken.currentAuthenticationToken.tokenString;
    NSString*rawNonce=self.currentNonce;
    FIROAuthCredential*credential=[FIROAuthProvidercredentialWithProviderID:@"facebook.com"
    IDToken:idTokenString
    rawNonce:rawNonce];
    

Authenticate with Identity Platform

Finally, authenticate with Identity Platform using the Identity Platform credential:

Swift

Auth.auth().signIn(with:credential){authResult,errorin
ifleterror=error{
letauthError=errorasNSError
ifisMFAEnabled,authError.code==AuthErrorCode.secondFactorRequired.rawValue{
// The user is a multi-factor user. Second factor challenge is required.
letresolver=authError
.userInfo[AuthErrorUserInfoMultiFactorResolverKey]as!MultiFactorResolver
vardisplayNameString=""
fortmpFactorInfoinresolver.hints{
displayNameString+=tmpFactorInfo.displayName??""
displayNameString+=" "
}
self.showTextInputPrompt(
withMessage:"Select factor to sign in\n\(displayNameString)",
completionBlock:{userPressedOK,displayNamein
varselectedHint:PhoneMultiFactorInfo?
fortmpFactorInfoinresolver.hints{
ifdisplayName==tmpFactorInfo.displayName{
selectedHint=tmpFactorInfoas?PhoneMultiFactorInfo
}
}
PhoneAuthProvider.provider()
.verifyPhoneNumber(with:selectedHint!,uiDelegate:nil,
multiFactorSession:resolver
.session){verificationID,errorin
iferror!=nil{
print(
"Multi factor start sign in failed. Error: \(error.debugDescription)"
)
}else{
self.showTextInputPrompt(
withMessage:"Verification code for \(selectedHint?.displayName??"")",
completionBlock:{userPressedOK,verificationCodein
letcredential:PhoneAuthCredential?=PhoneAuthProvider.provider()
.credential(withVerificationID:verificationID!,
verificationCode:verificationCode!)
letassertion:MultiFactorAssertion?=PhoneMultiFactorGenerator
.assertion(with:credential!)
resolver.resolveSignIn(with:assertion!){authResult,errorin
iferror!=nil{
print(
"Multi factor finanlize sign in failed. Error: \(error.debugDescription)"
)
}else{
self.navigationController?.popViewController(animated:true)
}
}
}
)
}
}
}
)
}else{
self.showMessagePrompt(error.localizedDescription)
return
}
// ...
return
}
// User is signed in
// ...
}

Objective-C

[[FIRAuthauth]signInWithCredential:credential
completion:^(FIRAuthDataResult*_NullableauthResult,
NSError*_Nullableerror){
if(isMFAEnabled && error && error.code==FIRAuthErrorCodeSecondFactorRequired){
FIRMultiFactorResolver*resolver=error.userInfo[FIRAuthErrorUserInfoMultiFactorResolverKey];
NSMutableString*displayNameString=[NSMutableStringstring];
for(FIRMultiFactorInfo*tmpFactorInfoinresolver.hints){
[displayNameStringappendString:tmpFactorInfo.displayName];
[displayNameStringappendString:@" "];
}
[selfshowTextInputPromptWithMessage:[NSStringstringWithFormat:@"Select factor to sign in\n%@",displayNameString]
completionBlock:^(BOOLuserPressedOK,NSString*_NullabledisplayName){
FIRPhoneMultiFactorInfo*selectedHint;
for(FIRMultiFactorInfo*tmpFactorInfoinresolver.hints){
if([displayNameisEqualToString:tmpFactorInfo.displayName]){
selectedHint=(FIRPhoneMultiFactorInfo*)tmpFactorInfo;
}
}
[FIRPhoneAuthProvider.provider
verifyPhoneNumberWithMultiFactorInfo:selectedHint
UIDelegate:nil
multiFactorSession:resolver.session
completion:^(NSString*_NullableverificationID,NSError*_Nullableerror){
if(error){
[selfshowMessagePrompt:error.localizedDescription];
}else{
[selfshowTextInputPromptWithMessage:[NSStringstringWithFormat:@"Verification code for %@",selectedHint.displayName]
completionBlock:^(BOOLuserPressedOK,NSString*_NullableverificationCode){
FIRPhoneAuthCredential*credential=
[[FIRPhoneAuthProviderprovider]credentialWithVerificationID:verificationID
verificationCode:verificationCode];
FIRMultiFactorAssertion*assertion=[FIRPhoneMultiFactorGeneratorassertionWithCredential:credential];
[resolverresolveSignInWithAssertion:assertioncompletion:^(FIRAuthDataResult*_NullableauthResult,NSError*_Nullableerror){
if(error){
[selfshowMessagePrompt:error.localizedDescription];
}else{
NSLog(@"Multi factor finanlize sign in succeeded.");
}
}];
}];
}
}];
}];
}
elseif(error){
// ...
return;
}
// User successfully signed in. Get user data from the FIRUser object
if(authResult==nil){return;}
FIRUser*user=authResult.user;
// ...
}];

What's next

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025年12月17日 UTC.