Swift · · 12 min read

Using Firebase to Integrate Facebook Login in iOS Apps

Using Firebase to Integrate Facebook Login in iOS Apps

Earlier, James walked you through how to use Firebase for user authentication with email/password. It is very common nowadays for developers to utilize some federated identity provider credentials such as Google Sign-in and Facebook Login, and let users to sign up the app with their own Facebook accounts. In this tutorial, we will see how to use Firebase Authentication to integrate with Facebook Login.

Editor’s note: This is a simplified version of a chapter from our Intermediate iOS 10 Programming with Swift book.

Before diving into the implementation, you probably have a question. Why do we need Firebase Authentication? Why not directly use the Facebook SDK to implement user authentication?

Even if you are going to use Firebase Authentication, it doesn’t mean you do not need the Facebook SDK. You still need to install the SDK in your Xcode project. However, with Firebase Authentication, most of the time you interact with the Firebase SDK that you are familiar with. Let me give you an example. This is the code snippet for retrieving the user’s display name after login:

if let currentUser = FIRAuth.auth()?.currentUser {
    nameLabel.text = currentUser.displayName
}

You should be very familiar with the code above if you have read through the previous chapter. Now let me ask you. How can you retrieve the user’s name for Facebook Login? Probably you will have to go through the Facebook SDK documentation to look up the corresponding API.

Let me tell you if you use Firebase Authentication and perform some integrations with Facebook Login, you can use the same Firebase API (as shown above) to retrieve the user’s name from his/her Facebook profile. Does this sound good to you?

This is one of the advantages for using Firebase Authentication to pair with other secure authentication services. And, you can manage all users (whether they use email, Facebook or Google to login) in the same Firebase console.

firebase-social-login-1

Prerequisite: Please go through Jame’s tutorial about Firebase login and sign up before going through this tutorial.

Now let’s begin to talk about the implementation. The implementation can be divided in three parts. Here is what we need to do:

  • Configure your Facebook app – to use Facebook login, you need to create a new app on its developer website, and go through some configurations such as App ID and App Secret.
  • Set up Facebook Login in Firebase – as you are going to use Firebase for Facebook Login, you will need to set up your app in Firebase console.
  • Integrate Firebase & Facebook SDK into your Xcode project – after all the configurations, the last step is to write code to implement Facebook Login through both Facebook and Firebase SDK.

That looks complicated. I will say the coding part is fairly straightforward, however, it will take you some time to do the configurations and project setup.

Okay, let’s get started.

The Demo Project

The demo project is very simple. The welcome screen displays two buttons: Sign In with Facebook and Sign In with Google. We will implement the Facebook login button in this tutorial. For the Google Sign in button, I will leave you as an exercise.

To help you focus on learning Facebook Login, you can download the starter project to get started. Once you download the starter project, open FirebaseDemo.xcworkspace and change the bundle identifier from com.appcoda.FirebaseDemoLogin to your own bundle identifier. This is important because this identifier must be unique.

The login process is very similar to that of email address. Say, when the user taps the Sign in with Facebook button for the first time, the app brings up a login screen for users. The login screen is provided by Facebook, and the user is required to sign in with his/her Facebook account. In addition to that, the user has to grant our app privileges to retrieve his/her email address and public profile (e.g. display name).

firebase-demo-app

If the user has the native Facebook app installed, the app will switch to the Facebook app to grant the permission. This is how a user logs in the app with Facebook Login for the first time. Facebook usually caches the user’s login, so the user do not need to sign in for subsequent login.

Creating a Firebase App

To integrate Facebook Login with Firebase, the very first thing is to create a Firebase app. Go to https://firebase.google.com and navigate to the console. Next, add a new project and name it to whatever name you want.

firebase-new-app

Once Firebase created the new project for you, it will take you to the overview. Here you select the iOS platform, and follow the on-screen procedures to fill in your bundle ID. Firebase will generate a file named GoogleService-Info.plist. Download it and add it to the Xcode project.

You can skip the precedures related to Firebase SDK installation as the starter project already bundled it. Just skip to the last step to complete the app configuration.

Setting a New Facebook App

As mentioned before, you will have to go through several configuration procedures. The next step is to set up a new Facebook app. Go to Facebook for Developers site, log in with your Facebook account. In the dropdown menu of My Apps, choose Add a new app. You will be prompted to give your app a display name and a category. I set the name to NorthernLights and choose Photo for category.

Next, click Create App ID to proceed. You will then be brought to a dashboard that you can configure Facebook Login.

Now choose +Add Product and then click Get Started next to the Facebook Login option. Choose iOS and Facebook will guide you through the integration process. You can ignore the instructions of Facebook SDK installation. Later we will use CocoaPods to install it. Just click Continue to proceed to the next step. Skip the second step for the same reason. In step 3 of the configuration, you’re required to provide the bundle ID of your project. Set it to the bundle ID you configured earlier and hit Save to save the change.

That’s it. You can skip the rest of the procedures. If you want to verify the bundle ID setting, click Settings in the side menu. You should see a section about iOS that shows the bundle ID.

In the Settings screen, you should find your App ID and App Secret. By default, App Secret is masked. You can click the Show button to reveal it. We need these two pieces of information for Firebase configuration.

Configuring Facebook Login in Firebase

Now head back to the Firebase console and select the app you created (here, I used Northern Lights). In the side menu, choose Authentication and then select Sign-in Method.

As we are now implementing Facebook Login, click Facebook and flip the switch to ON. You have to fill in two options here: App ID and App Secret. These are the values you revealed in the settings of your Facebook app. Fill them in accordingly and hit Save to save the changes.

You may notice the OAuth redirect URI. Google APIs use the OAuth 2.0 protocol for authentication and authorization. After a user logs in with his/her Facebook account and grants the access permissions, Facebook will inform Firebase through a callback URL. Here, the OAuth redirect URI is the URL.

You have to copy this URI and add it to your Facebook app configuration. Now go back to your Facebook app. Under Facebook Login in the side menu, choose Settings. Make sure you paste the URI that you copied earlier in the Valid OAuth redirect URIs field. Hit Save Changes to save the settings.

Great! You have completed the configuration for both your Facebook app and Firebase.

Setting Up the Project with Firebase and Facebook SDK

You will need both the Firebase and Facebook SDK. The easiest way to install both SDKs is by using CocoaPods. To add the SDKs to the project, edit the Podfile like this:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'FirebaseDemo' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for FirebaseDemo
  pod 'Firebase/Core'
  pod 'Firebase/Auth'

  # Pods for Facebook
  pod 'Bolts'
  pod 'FBSDKCoreKit'
  pod 'FBSDKLoginKit'
end
Note: If you are using the starter project, it already installed with the Firebase SDK. So the Podfile comes with the Core and Auth pods of Firebase.

After the changes, open Terminal and change to the project folder. Then type the following command to install the pods (please make sure you close your Xcode project before running the command):

pod install

If everything goes smoothly, CocoaPods will download the specified SDKs and bundle them in the Xcode project.

firebase-social-login-10

Configuring the Xcode Project

There is one more configuration before we dive into the Swift code. Open FirebaseDemo.xcworkspace. In project navigator, right click the Info.plist file and choose Open as > Source code. This will open the file, which is actually an XML file, in text format.

Insert the following XML snippet before the </dict> tag:

CFBundleURLTypes

  
    CFBundleURLSchemes
    
      fb564148470450124
    
  

FacebookAppID
564148470450124
FacebookDisplayName
Northern Lights
LSApplicationQueriesSchemes

  fbapi
  fb-messenger-api
  fbauth2
  fbshareextension

The snippet above is my own configuration. Yours should be different from mine, so please make the following changes:

  • Change the App ID (564148470450124) to your own ID. You can reveal this ID in the dashboard of your Facebook app.
  • Change fb564148470450124 to your own URL scheme. Replace it with fb{your app ID}.
  • Change the display name of the app (i.e. Northern Lights) to your own name.

The Facebook APIs will read the configuration in Info.plist for connecting your Facebook app and managing the Facebook Login. You have to ensure the App ID matches the one you created in the earlier section.

The LSApplicationQueriesSchemes key specifies the URL schemes your app can use with the canOpenURL: method of the UIApplication class. If the user has the official Facebook app installed, it may switch to the app for login purpose. In such case, it is required to declare the required URL schemes in this key, so that Facebook can properly perform the app switch.

Diving into the Swift Code

Finally, after all the cumbersome configurations, it is time to discuss the Swift code. Now open AppDelegate.swift and insert the following import statement:

import Firebase
import FBSDKCoreKit

In the application(_:didFinishLaunchingWithOptions:) method, insert a couple lines of code to initialize Firebase and configure Facebook Login:

FIRApp.configure()
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)

In the same class, add the following method:

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    let handled = FBSDKApplicationDelegate.sharedInstance().application(app, open: url, options: options)
    
    return handled
}

What are the code above for? FBSDKApplicationDelegate is designed for post processing results from Facebook Login (e.g. switching over to the native Facebook app) or Facebook Dialogs (similar to the web interface of Facebook). It is required to call the application method in order to properly use the Facebook SDK in the application(_:didFinishLaunchingWithOptions:) method.

As mentioned before, the Facebook Login process can happen like this:

  • The user taps the Sign in with Facebook button.
  • Assuming that the user has the native Facebook app installed, the app will switch to the Facebook app to ask for the user’s permission.
  • After the user’s approval, the Facebook app will switch back to our app, passing us the user’s credential, and continue the login process.

When the Facebook app switches back to our app, the application(_:open:options:) method will be invoked. So we have to implement the method to handle the Facebook Login. To properly handle the login, it is required by Facebook to call the application method of FBSDKApplicationDelegate:

FBSDKApplicationDelegate.sharedInstance().application(app, open: url, options: options)

Now open to WelcomeViewController.swift. This is the view controller of the Welcome screen that shows the Facebook Login button. In the WelcomeViewController class, first add a couple of import statements to import the required SDK:

import FBSDKLoginKit
import Firebase

Then insert an action method for handling Facebook Login:

@IBAction func facebookLogin(sender: UIButton) {
    let fbLoginManager = FBSDKLoginManager()
    fbLoginManager.logIn(withReadPermissions: ["public_profile", "email"], from: self) { (result, error) in
        if let error = error {
            print("Failed to login: \(error.localizedDescription)")
            return
        }
        
        guard let accessToken = FBSDKAccessToken.current() else {
            print("Failed to get access token")
            return
        }

        let credential = FIRFacebookAuthProvider.credential(withAccessToken: accessToken.tokenString)
        
        // Perform login by calling Firebase APIs
        FIRAuth.auth()?.signIn(with: credential, completion: { (user, error) in
            if let error = error {
                print("Login error: \(error.localizedDescription)")
                let alertController = UIAlertController(title: "Login Error", message: error.localizedDescription, preferredStyle: .alert)
                let okayAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
                alertController.addAction(okayAction)
                self.present(alertController, animated: true, completion: nil)
                
                return
            }
            
            // Present the main view
            if let viewController = self.storyboard?.instantiateViewController(withIdentifier: "MainView") {
                UIApplication.shared.keyWindow?.rootViewController = viewController
                self.dismiss(animated: true, completion: nil)
            }
            
        })

    }   
}

If you’ve read our Firebase tutorial, it is pretty similar to the code we use when implementing email/password authentication, except the code related to FBSDKLoginManager. The FBSDKLoginManager class provides methods for logging a user in and out. For login, you can call the logIn method and specify the read permission you want to ask for. Since we need the email address and the display name of the user, we will ask the user for the read permission of public_profile and email.

After the user signs in with Facebook, whether he/she grants our app permission or not, the complete handler will be called. Here we first check if there is any error. If not, we proceed to retrieve the access token for the user and convert it to a Firebase credential by calling:

FIRFacebookAuthProvider.credential(withAccessToken: accessToken.tokenString)

You should be very familiar with the rest of the code. We call the signIn method of FIRAuth with the Facebook credential. If there is any error, we present an error dialog. Otherwise, we display the home screen and dismiss the current view controller.

Now switch to Main.storyboard, and choose the Welcome View Controller Scene. Control drag from the Sign In With Facebook button to the view controller icon of the dock. Release the buttons and select facebookLoginWithSender: in the popover menu to connect the action method.

firebase-demo-app-actionmethod

Setting Up Test Accounts

It’s time to test the app. If you tap the Sign In with Facebook button, you should see the login screen of Facebook. However, your Facebook app that you configured earlier is still in development mode. If you log in the app with your own Facebook account, you will see an error:

App Not Setup: This app is still in development mode, and you don't have access to it. Switch to a registered test user or ask an app admin for permissions.

Now you have two options to test the app:

  1. Switch your Facebook app to production mode – you can change your Facebook app from development mode to production in the developer dashboard.
  2. Create a test user (or multiple test accounts) for testing purpose – Facebook allows developers to create a test account to perform testing when the Facebook app is in development mode.

During the development stage of an app, and especially when authentication is involved in it, it’s generally a bad habit to use your normal account to perform all the required testings. Therefore, we will first opt for option 2.

Now go back to the Facebook Developer dashboard and select Northern Lights. In the side bar menu, choose Roles > Test Users.

Here you can click the Add button to add a new test user. In the popover menu, set the number of test users to 1 and then hit the Create Test Users button. Facebook will then generate a test user with random name and email address. Click the Edit button next to the new test user and select Change the name or password for this test user to modify its password.

Testing Facebook Login

Great! You are now ready to test the app. Run the app and select Sign In with Facebook when it launches. Log in with the test account you just created. If everything goes smoothly, you should be able to access the home screen.

firebase-demo-app

Facebook will cache your login status. So next time, you no longer need to sign the app with your test account (or Facebook account) again.

Logout and User Display Name

How about logout and user profile? Do we need to use specific API calls from the Facebook SDK? You can use the same code snippet to retrieve the display name from the user’s Facebook profile.

if let currentUser = FIRAuth.auth()?.currentUser {
    nameLabel.text = currentUser.displayName
}

Firebase is smart enough to determine the appropriate display name in reference to the login method (whether it is from Facebook or uses email/password).

For logout, we can use the same API to log a user out.

FIRAuth.auth()?.signOut()

That is the power of Firebase. You can utilize the same API calls, and Firebase will handle the handle the heavy lifting for you.

Summary

In this tutorial, I walked you through how to use Firebase to integrate with Facebook Login. I intentionally left out the Google Sign-in button unimplemented. Try to refer the Google Sign In documentation and see if you manage to enable the app with Google Sign In.

For reference, you can download the complete project on GitHub.

Editor’s note: This is a simplified version of a chapter from our Intermediate iOS 10 Programming with Swift book. If you find this article useful, you will very likely enjoy reading our book.

Read next