Navigation

Add Facebook OAuth to the To-Do Client

Deployment Type:

Author: MongoDB Documentation Team

This tutorial walks you through adding the Facebook OAuth provider to your Stitch app and To-do client(s). The following diagram outlines the OAuth process in a Stitch application:

../../../_images/oauth.png

Time required: 30 minutes

What You’ll Need

  • If you have not yet built the To-do backend, follow the steps in this guide.
  • A Facebook developer account
  • If you are building on a previous tutorial, be sure to remove and reinstall node dependencies, so you are working with the most up-to-date SDKs.

Procedure

Note

This tutorial is written with the latest information from Facebook on implementing OAuth in your app. However, Facebook may make changes at any time that would cause some of the following steps to be out of date. To learn about any breaking changes, refer to the official Android and iOS documentation from Facebook.

A. Set up the Backend

To implement Facebook OAuth in your Stitch project, you create a new Facebook client credential, and then enable the Facebook Auth provider in your Stitch backend.

1

Create an app in Facebook.

To authenticate using Facebook’s OAuth provider, you need to create a Facebook app using your Facebook Developer account. When you do this, Facebook generates an app ID and secret, which you will use to configure both the Stitch backend and your Android app.

  1. Log in to your Facebook Developer account. If you do not have a Facebook developer account, see Facebook - Register and Configure an App. You will also need to create a regular Facebook account if you do not already have one.

  2. Add a new Facebook application.

  3. Once created, your application view opens to Select a Scenario.

  4. Click User Email and Public Profile, and then click confirm. You will be redirected to Basic Settings page for your new app.

  5. In the left-hand navigation, expand Facebook Login, and then click Quickstart.

  6. Depending on which client you are building, click the appropriate platform in the UI, and then follow these steps for that same platform:

    In the Quick Start for Web, there is only one required step:

    • For the site URL, enter http://localhost:3000

    The remaining Quick Start steps show you how you can integrate the Facebook login to your Web application. You will not need this information when using Stitch.

    In the Quick Start for Android:

    1. You can skip both the Download the Facebook SDK for Android and Import the Facebook SDK steps.

    2. For Tell Us about Your Android Project step, enter the following:

      • For Package Name, enter:
      com.mongodb.stitch.android.tutorials.todo
      
      • For Default Activity Class Name, enter:
      com.mongodb.stitch.android.tutorials.todo.TodoListActivity
      
    3. Click Save. You will prompted to verify the Google Play Package Name since your app is not listed publicly on Google Play. Click Use this package name, and then continue to the next step.

    4. Generate the development key hash per instructions, click Save, and then click Continue.

    5. Optional. You can enable/disable Single Sign On, and then click Next.

    6. Copy the facebook_app_id and fb_login_protocol_scheme values:

      <string name="facebook_app_id">012345678900000</string>
      <string name="fb_login_protocol_scheme">fb1234985978493875</string>
      
    7. Also copy the first element of the meta-data section:

      <meta-data android:name="com.facebook.sdk.ApplicationId"
            android:value="@string/facebook_app_id"/>
      

      You will use these entries during the setup step of the ToDo Android project in this tutorial.

    8. You can omit the remaining steps as they are already incorporated into the To-do Android project.

    In the Quick Start for iOS:

    1. Be sure the development dropdown is set to SDK: Cocoapods.

    2. Enter the following for the bundle identifier

      com.mongodb.Todo
      
    3. Click Save, and then click Continue

    The remaining steps in the Quickstart are not needed at this point and will be covered later in step B.5

  7. In the left-hand navigation menu, under Facebook Login, click Settings.

  8. In the Valid OAuth redirect URIs field, add the following entry, and then save the changes:

    https://stitch.mongodb.com/api/client/v2.0/auth/callback
    
  9. In the left-hand navigation near the top, click App Profile. Copy the App ID and App Secret values. You will use these values when configuring the MongoDB Stitch Facebook Auth provider in the next steps.

2

Configure the Facebook Authentication Provider in Stitch.

Now that you have generated a Facebook app ID and secret, you can enable the Facebook auth provider in your Stitch backend app.

  1. Navigate to your Stitch application.
  2. Select Users from the left-side navigation.
  3. Select the Providers tab.
  4. Select Users from the left-side navigation.
  5. For Facebook, click the Edit button.
  6. In the Facebook provider settings:
    • Switch the Provider Status toggle to enabled.
    • Enter your new Facebook App ID in the Client ID field and Facebook App Secret in Client Secret field.
  7. Click Save.

Deploy Your Changes

Before moving on, be sure to Review and Deploy Changes to your Stitch app. You can do this by clicking the button in the blue bar at the top of your screen, or by clicking Deploy in the left sidebar.

B. Update your client

For the client-side app development in this tutorial, you can start with the app you built in the first tutorial or start with an app that already has some of the Android structural work done for you.

Note

If you chose to use your existing app, you will need to create a new layout file and class to handle the logon UI and logic. We recommend you view the layout file in the pre-configured app for ideas on how this might be strcutured. The steps in this tutorial assume you are using the pre-configured app.

1

Get the latest code

In the MongoDB Stitch Android tutorial repo, you will use the facebook-oauth branch, which contains two tags:

  • facebook_oauth_start, which provides the basic structure for this tutorial, and
  • facebook_oauth_end, which is the completed app as it should look at the end of this tutorial.

If you have not yet cloned the repo, run the following command:

git clone git@github.com:mongodb-university/stitch-tutorial-todo-android.git

To get the tagged start for this tutorial, run the following command from the directory of your local repo:

git checkout facebook_oauth_start

Note that the Android project now includes a LogonActivity.java file and logon.xml layout file. The layout provides the UI for logging in with Facebook OAuth, and the LogonActivity class renders the login screen and handles the authentication process.

2

Add Google Libraries to Gradle

  1. Open the project-level Gradle file.

  2. Add the following line to the dependencies to bring in the Facebook SDK:

    implementation 'com.facebook.android:facebook-login:[5,6)'
    
3

Update strings.xml

The strings.xml file holds string variables for your app. The Facebook login process specifically looks for two values in your strings.xml file: facebook_app_id and fb_login_protocol_scheme. In addition, you need to add your Stitch app ID if you have not previously done so.

  1. Open the res/values/strings.xml file.
  2. Replace APP_ID with your Stitch App ID.
  3. Replace Facebook_App_ID and Facebook_Scheme with the facebook_app_id and fb_login_protocol_scheme values that Facebook generated during the Facebook setup process.
4

Add a button to logon.xml

The logon.xml file defines the logon activity layout, which currently only inlcudes a link for logging on anonymously.

  1. At the bottom of the LinearLayout, add a com.facebook.login.widget.LoginButton. The android:id property should be set to @+id/fb_login_button. Your code should look like the following:

    <com.facebook.login.widget.LoginButton
      android:id="@+id/fb_login_button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
    />
    
5

Update AndroidManifest.xml

For the default Facebook login button to work correctly, you need to update your manifest file.

  1. Open the AndroidManifest.xml file.

  2. Add the following code inside the <application> section:

    <meta-data android:name="com.facebook.sdk.ApplicationId"
       android:value="@string/facebook_app_id"/>
    
6

Add logon logic to LogonActivity.java

All of the logon logic for this app lives in the LogonActivity class, which displays the Logon screen when the app starts. Once a user authenticates (currently only as Anonymous), control is passed to the TodoListActivity class. We are now going to add the logic for Facebook OAuth to the logon activity, so a user can choose to authenticate either as Anonymous or with their Facebook account.

Open the LogonActivity.java file and find the enableFacebookAuth method stub; you will add the Facebook login logic in this method stub.

  1. In the enableFacebookAuth method stub, initialize the CallbackManager, which is the Facebook class that handles the login response from Facebook. To do this, call CallbackManager.Factory.create():

    // 1. Initialize the CallbackManager
    _callbackManager = CallbackManager.Factory.create();
    
  2. Register the CallbackManager with the LoginManager, which handles the response from Facebook. To get you started, we have added the following method stub, which includes listeners for onSuccess, onCancel, and onError:

    // 2. Register the CallbackManager with the LoginManager instance
       LoginManager.getInstance().registerCallback(_callbackManager,
          new FacebookCallback<LoginResult>() {
             @Override
             public void onSuccess(LoginResult loginResult) {
    
                // 3. On successful login, obtain the Facebook credential
                //  and pass it to Stitch via the loginWithCredential() method.
    
             }
    
             @Override
             public void onCancel() {
                Toast.makeText(
                   LogonActivity.this,
                   "Facebook logon was cancelled.",
                   Toast.LENGTH_LONG)
                .show();
             }
    
             @Override
             public void onError(final FacebookException exception) {
                Toast.makeText(
                   LogonActivity.this,
                   "Failed to logon with Facebook. Result: " + exception.toString(),
                   Toast.LENGTH_LONG)
                .show();
    
             }
       });
    
  3. Add the logic to authenticate with Stitch upon successful Facebook authentication. In the onSuccess listener, generate a FacebookCredential from the returned AccessToken, and then call the Stitch client’s loginWithCredential() method. Make sure to add a listener for task.isSuccessful(), which indicates that the user is now authenticated against Stitch. In this listener, call the Activity’s setResult() and finish() methods to close the Login Activity.

    When complete, the onSuccess listener should look like the following:

    @Override
    public void onSuccess(LoginResult loginResult) {
        // 3. On successful login, obtain the Facebook credential and
        // pass it to Stitch via the loginWithCredential() method.
    
        final FacebookCredential fbCredential = new
             FacebookCredential(AccessToken.getCurrentAccessToken().getToken());
        TodoListActivity.client.getAuth()
             .loginWithCredential(fbCredential).addOnCompleteListener(task -> {
             if (task.isSuccessful()) {
                   // 4. We have successfully logged on with Stitch, so set the activity's
                   // result and call finish();
                   setResult(Activity.RESULT_OK);
                   finish();
             } else {
                   Log.e("Stitch Auth", "Error logging in with Facebook",
                         task.getException());
             }
        });
    }
    
  4. Add a call to _callbackManager.onActivityResult in the LoginActivity’s onActivityResult listener. When complete, the complete onActivityResult method should look like this:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       super.onActivityResult(requestCode, resultCode, data);
    
       // 4. Handle the result that Facebook returns to us
       _callbackManager.onActivityResult(requestCode, resultCode, data);
    }
    
  5. Finally, make sure that the user is logged out of both Stitch and Facebook when they log out of the app. Otherwise, the app will preserve the Facebook credentials. When a user logs out of the app, we log out of Stitch in the onClick handler for the logout button and then redirect to the LogonActivity. So, in the setupLogin() method (which is called when the LogonActivity loads), you will add code to check if there is a Facebook user logged in, and if so, log them out. Use the AccessToken class to get the current access token. If the token isn’t null and hasn’t expired, call LoginManager.getInstance().logOut():

    // 5. Make sure that the current user is logged off whenever
    // the login activity is shown.
    AccessToken accessToken = AccessToken.getCurrentAccessToken();
    boolean isLoggedIn = accessToken != null && !accessToken.isExpired();
    if (isLoggedIn) {
          LoginManager.getInstance().logOut();
    }
    

C. Build and Test

You can now run the app (in the emulator or on a device). You will see the logon screen with the newly-added Facebook button:

../../../_images/android-todo-facebook-login.png

Log in, add some items to your To-do list, and then log out (from the menu). When you log in again with the same account, your to-do list is shown. In addition, if you log on from other client apps that use the same Facebook and Stitch backend app, you will see your your to-do list.

Security Warning

Because of the authentication flow on iOS, Facebook OAuth is NOT recommended for multi-user devices.

A. Set up the Backend

To implement Facebook OAuth in your Stitch project, create a new Facebook client credential, and then enable the Facebook Auth provider in your Stitch backend.

1

Create an app in Facebook.

To authenticate using Facebook’s OAuth provider, you need to create a Facebook app using your Facebook Developer account. When you do this, Facebook generates an app ID and secret, which you will use to configure both the Stitch backend and your Android app.

  1. Log in to your Facebook Developer account. If you do not have a Facebook developer account, see Facebook - Register and Configure an App. You will also need to create a regular Facebook account if you do not already have one.

  2. Add a new Facebook application.

  3. Once created, your application view opens to Select a Scenario.

  4. Click User Email and Public Profile, and then click confirm. You will be redirected to Basic Settings page for your new app.

  5. In the left-hand navigation, expand Facebook Login, and then click Quickstart.

  6. Depending on which client you are building, click the appropriate platform in the UI, and then follow these steps for that same platform:

    In the Quick Start for Web, there is only one required step:

    • For the site URL, enter http://localhost:3000

    The remaining Quick Start steps show you how you can integrate the Facebook login to your Web application. You will not need this information when using Stitch.

    In the Quick Start for Android:

    1. You can skip both the Download the Facebook SDK for Android and Import the Facebook SDK steps.

    2. For Tell Us about Your Android Project step, enter the following:

      • For Package Name, enter:
      com.mongodb.stitch.android.tutorials.todo
      
      • For Default Activity Class Name, enter:
      com.mongodb.stitch.android.tutorials.todo.TodoListActivity
      
    3. Click Save. You will prompted to verify the Google Play Package Name since your app is not listed publicly on Google Play. Click Use this package name, and then continue to the next step.

    4. Generate the development key hash per instructions, click Save, and then click Continue.

    5. Optional. You can enable/disable Single Sign On, and then click Next.

    6. Copy the facebook_app_id and fb_login_protocol_scheme values:

      <string name="facebook_app_id">012345678900000</string>
      <string name="fb_login_protocol_scheme">fb1234985978493875</string>
      
    7. Also copy the first element of the meta-data section:

      <meta-data android:name="com.facebook.sdk.ApplicationId"
            android:value="@string/facebook_app_id"/>
      

      You will use these entries during the setup step of the ToDo Android project in this tutorial.

    8. You can omit the remaining steps as they are already incorporated into the To-do Android project.

    In the Quick Start for iOS:

    1. Be sure the development dropdown is set to SDK: Cocoapods.

    2. Enter the following for the bundle identifier

      com.mongodb.Todo
      
    3. Click Save, and then click Continue

    The remaining steps in the Quickstart are not needed at this point and will be covered later in step B.5

  7. In the left-hand navigation menu, under Facebook Login, click Settings.

  8. In the Valid OAuth redirect URIs field, add the following entry, and then save the changes:

    https://stitch.mongodb.com/api/client/v2.0/auth/callback
    
  9. In the left-hand navigation near the top, click App Profile. Copy the App ID and App Secret values. You will use these values when configuring the MongoDB Stitch Facebook Auth provider in the next steps.

2

Configure the Facebook Authentication Provider in Stitch.

Now that you have generated a Facebook app ID and secret, you can enable the Facebook auth provider in your Stitch backend app.

  1. Navigate to your Stitch application.
  2. Select Users from the left-side navigation.
  3. Select the Providers tab.
  4. Select Users from the left-side navigation.
  5. For Facebook, click the Edit button.
  6. In the Facebook provider settings:
    • Switch the Provider Status toggle to enabled.
    • Enter your new Facebook App ID in the Client ID field and Facebook App Secret in Client Secret field.
  7. Click Save.

Deploy Your Changes

Before moving on, be sure to Review and Deploy Changes to your Stitch app. You can do this by clicking the button in the blue bar at the top of your screen, or by clicking Deploy in the left sidebar.

B. Update your client

For the client-side app development in this tutorial, we assume you are continuing with the app you built in the first tutorial.

If you would like to follow along with this tutorial, you can clone the application from the master branch of stitch-tutorial-todo-ios, or to see it implemented you can checkout the facebook-oauth branch.

1

Modify Podfile

It’s time to jump into Xcode. Open your Todo.xcworkspace project and find the Pods project. Open Podfile and add the following line after the line beginning with pod 'StitchSDK', ... to add support for Google Signin.

pod 'FacebookCore'
pod 'FacebookLogin'

Exit Xcode, and in the project directory run the following command to have Cocoapods add the new dependency,

pod install --repo-update

Once this is complete reopen Todo.xcworkspace

2

Modify AppDelegate.swift

Now it’s time to modify AppDelegate.swift to allow our application to support signing in with Facebook.

First, add the following import right after the line import StitchRemoteMongoDBService.

import FBSDKLoginKit

Now it’s time to set up the Google Sign In instance. Within the lifecyle function didFinishLaunchingWithOptions, add the following code before the window set-up logic.

// facebook sign in
ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)

We must also add a required method that will be called when the OAuth URL is opened.

// added for facebook sign in
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    return  ApplicationDelegate.shared.application(app, open: url, options: options)
}
3

Modify WelcomeViewController.swift

In the previous version of this application where we only supported Anonymous Login, we were using an AlertController to log in. This worked for our needs then, but now we’d like to show the Facebook Sign In button.

We elect to create a custom Facebook Login button to control the styling and ensure it calls our custom selector.

We also need to add this view controller as a listener to the NotificationCenter for “SIGN_IN” events in order to move our view flow forward to the TodoTableViewController. In the future we can use this to add other authentication mechanisms and reuse the same sign in logic.

Replace the entire contents of WelcomeViewController.swift with the following:

import UIKit
import MongoSwift
import StitchCore
import FBSDKLoginKit
import FacebookCore
import FacebookLogin

class WelcomeViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        title = "Welcome"
        // add self as observer to NotificationCenter
        NotificationCenter.default.addObserver(self, selector: #selector(didSignIn), name: NSNotification.Name("SIGN_IN"), object: nil)
        // Do any additional setup after loading the view.

        if stitch.auth.isLoggedIn {
            self.navigationController?.pushViewController(TodoTableViewController(), animated: true)
        } else {

            // anonymous login button
            let anonymousButton = UIButton(frame: CGRect(x: self.view.frame.width / 2 - 150, y: 100, width: 300, height: 50))
            anonymousButton.backgroundColor = .green
            anonymousButton.setTitle("Login Anonymously", for: .normal)
            anonymousButton.addTarget(self, action: #selector(didClickAnonymousLogin), for: .touchUpInside)


            // facebook login button
            let fbButton = UIButton(frame: CGRect(x: self.view.frame.width / 2 - 150, y: 300, width: 300, height: 50))
            fbButton.backgroundColor = .darkGray
            fbButton.setTitle("Login with Facebook", for: .normal)
            fbButton.addTarget(self, action: #selector(didClickFacebookLogin), for: .touchUpInside)


            // adding buttons to the view
            self.view.addSubview(anonymousButton)
            self.view.addSubview(fbButton)

        }
    }

    // this will be called when the user clicks our fbButton
    @objc func didClickFacebookLogin(_ sender: Any) {
        let loginManager = LoginManager()
        loginManager.logIn(permissions: [.publicProfile, .email], viewController: self) { result in
            switch result {
            case .failed(let error):
                print(error.localizedDescription)
            case .cancelled:
                print("cancelled")
            case .success(_, _, let accessToken):
                let fbCredential = FacebookCredential.init(withAccessToken: accessToken.tokenString)
                stitch.auth.login(withCredential: fbCredential) { result in
                    switch result {
                    case .success:
                        NotificationCenter.default.post(name: Notification.Name("SIGN_IN"), object: nil, userInfo: nil)
                    case .failure(let error):
                        print("failed logging in Stitch with Facebook. error: \(error)")
                        LoginManager().logOut()
                    }
                }
            }
        }
    }


    @objc func didClickAnonymousLogin(_ sender: Any) {
        stitch.auth.login(withCredential: AnonymousCredential()) { result in
            switch result {
            case .failure(let e):
                fatalError(e.localizedDescription)
            case .success:
                NotificationCenter.default.post(name: Notification.Name("SIGN_IN"), object: nil, userInfo: nil)

            }
        }
    }

    @objc func didSignIn(_sender: Any) {
        DispatchQueue.main.sync {
            self.navigationController?.pushViewController(TodoTableViewController(), animated: true)
        }
    }
4

Modify TodoTableViewController.swift

We’re almost finished, only a few items remaining! We need to modify our logout functionality in TodoTableViewController. We’ll add a check to determine whether the user was logged in with Facebook. If so, we’ll call the LoginManager().logout() method. To do this, we’ll also make sure to import FBSDKLoginKit.

Add the following import to the top of the file:

import FBSDKLoginKit

Now, modify your logout function to match the following:

@objc func logout(_ sender: Any) {
   // check whether the user is logged in with Facebook
    if stitch.auth.currentUser?.loggedInProviderType == .some(.facebook) {
        LoginManager().logout()
    }
    stitch.auth.logout { result in
        switch result {
        case .failure(let e):
            print("Had an error logging out: \(e)")
        case .success:
            DispatchQueue.main.async {
                self.navigationController?.setViewControllers([WelcomeViewController()], animated: false)
            }
        }
    }
}
5

Add URL Types Information

The last thing we need to do is allow our application to call the Facebook OAuth URL for our iOS client.

To do this, navigate to your Facebook Apps page and select PRODUCTS. Select Facebook Login and then Quickstart.

Follow the steps through step 4a to get the necessary information to add to your application’s Info.plist file.

C. Build and Test

You can now run the app (in the emulator or on a device). You will see the logon screen with the newly-added Facebook button:

../../../_images/ios-todo-facebook-login.png

Log in, add some items to your To-do list, and then log out (from the menu). When you log in again with the same account, your to-do list is shown. In addition, if you log on from other client apps that use the same Facebook application, you can see your to-do list and items there.

A. Set up the Backend

To implement Facebook OAuth in your Stitch project, create a new Facebook client credential, and then enable the Facebook Auth provider in your Stitch backend.

1

Create an app in Facebook.

To authenticate using Facebook’s OAuth provider, you need to create a Facebook app using your Facebook Developer account. When you do this, Facebook generates an app ID and secret, which you will use to configure both the Stitch backend and your Android app.

  1. Log in to your Facebook Developer account. If you do not have a Facebook developer account, see Facebook - Register and Configure an App. You will also need to create a regular Facebook account if you do not already have one.

  2. Add a new Facebook application.

  3. Once created, your application view opens to Select a Scenario.

  4. Click User Email and Public Profile, and then click confirm. You will be redirected to Basic Settings page for your new app.

  5. In the left-hand navigation, expand Facebook Login, and then click Quickstart.

  6. Depending on which client you are building, click the appropriate platform in the UI, and then follow these steps for that same platform:

    In the Quick Start for Web, there is only one required step:

    • For the site URL, enter http://localhost:3000

    The remaining Quick Start steps show you how you can integrate the Facebook login to your Web application. You will not need this information when using Stitch.

    In the Quick Start for Android:

    1. You can skip both the Download the Facebook SDK for Android and Import the Facebook SDK steps.

    2. For Tell Us about Your Android Project step, enter the following:

      • For Package Name, enter:
      com.mongodb.stitch.android.tutorials.todo
      
      • For Default Activity Class Name, enter:
      com.mongodb.stitch.android.tutorials.todo.TodoListActivity
      
    3. Click Save. You will prompted to verify the Google Play Package Name since your app is not listed publicly on Google Play. Click Use this package name, and then continue to the next step.

    4. Generate the development key hash per instructions, click Save, and then click Continue.

    5. Optional. You can enable/disable Single Sign On, and then click Next.

    6. Copy the facebook_app_id and fb_login_protocol_scheme values:

      <string name="facebook_app_id">012345678900000</string>
      <string name="fb_login_protocol_scheme">fb1234985978493875</string>
      
    7. Also copy the first element of the meta-data section:

      <meta-data android:name="com.facebook.sdk.ApplicationId"
            android:value="@string/facebook_app_id"/>
      

      You will use these entries during the setup step of the ToDo Android project in this tutorial.

    8. You can omit the remaining steps as they are already incorporated into the To-do Android project.

    In the Quick Start for iOS:

    1. Be sure the development dropdown is set to SDK: Cocoapods.

    2. Enter the following for the bundle identifier

      com.mongodb.Todo
      
    3. Click Save, and then click Continue

    The remaining steps in the Quickstart are not needed at this point and will be covered later in step B.5

  7. In the left-hand navigation menu, under Facebook Login, click Settings.

  8. In the Valid OAuth redirect URIs field, add the following entry, and then save the changes:

    https://stitch.mongodb.com/api/client/v2.0/auth/callback
    
  9. In the left-hand navigation near the top, click App Profile. Copy the App ID and App Secret values. You will use these values when configuring the MongoDB Stitch Facebook Auth provider in the next steps.

2

Configure the Facebook Authentication Provider in Stitch.

Now that you have generated a Facebook app ID and secret, you can enable the Facebook auth provider in your Stitch backend app.

  1. Navigate to your Stitch application.
  2. Select Users from the left-side navigation.
  3. Select the Providers tab.
  4. Select Users from the left-side navigation.
  5. For Facebook, click the Edit button.
  6. In the Facebook provider settings:
    • Switch the Provider Status toggle to enabled.
    • Enter your new Facebook App ID in the Client ID field and Facebook App Secret in Client Secret field.
  7. Click Save.

Deploy Your Changes

Before moving on, be sure to Review and Deploy Changes to your Stitch app. You can do this by clicking the button in the blue bar at the top of your screen, or by clicking Deploy in the left sidebar.

B. Update your client

For the client-side app development in this tutorial, we assume you are continuing with the app you built in the first tutorial.

If you would like to follow along with this tutorial, you can clone the application from the master branch of stitch-tutorial-todo-web, or to see it implemented you can checkout the facebook-oauth branch.

1

Add a Stitch Authentication Event Listener

In this section, you will alter the pre-existing React code for anonymous login to be compatible with Faebook OAuth. Namely, you will set up an event listener to determine when login occurs. The Stitch Browser SDK allows you to set up event listeners that can automatically respond to authentication events in your client application, such as when a user logs in or out.

  1. Add the following two functions to stitch/authentication.js. These two functions add and remove listeners, resepctively, based on a provided listener argument. You will build one such listener in the upcoming steps and will then better understand its structure.

    export function addAuthenticationListener(listener) {
        app.auth.addAuthListener(listener);
    }
    export function removeAuthenticationListener(listener) {
        app.auth.removeAuthListener(listener);
    }
    
  2. Now that you can add and remove authentication listeners, you need to actually create a listener object and add it in the React code. Add addAuthenticationListener and removeAuthenticationListener to your import from stitch/authentication.js in StitchAuth.js:

      import {
          hasLoggedInUser,
          loginAnonymous,
          logoutCurrentUser,
          getCurrentUser,
          addAuthenticationListener,
          removeAuthenticationListener,
      } from "./../stitch/authentication";
    
  3. Once you’ve imported the functions, you can use React’s effect hook to add the authentication listener when the app first loads and remove the listener when the app unmounts or the user navigates away. Before you can use the hook, import useEffect from React. This is what the very first line of StitchAuth.js should look like after doing so:

    import React, {useEffect} from "react";
    
  4. Now that useEffect has been imported, add the following code block directly above the handleAnonymousLogin function in StitchAuth.js:

    useEffect(() => {
        const authListener = {
            onUserLoggedIn: (auth, loggedInUser) => {
            if (loggedInUser) {
                setAuthState(authState => ({
                ...authState,
                isLoggedIn: true,
                currentUser: loggedInUser,
                }));
            }
            },
            onUserLoggedOut: (auth, loggedOutUser) => {
            setAuthState(authState => ({
                ...authState,
                isLoggedIn: false,
                currentUser: null,
            }));
            }
        };
        addAuthenticationListener(authListener);
        setAuthState(state => ({ ...state}));
        return () => {
            removeAuthenticationListener(authListener);
        };
    }, []);
    
  5. In the exisiting code, there is a handleAnonymousLogin function that (as its name implies) is specific to anonymous login. In this step, you will create the more generic handleLogin function, which will allow us to use multiple auth providers. Replace the entire handleAnonymousLogin function with the following:

    const handleLogin = async (provider) => {
      if (!authState.isLoggedIn) {
          switch(provider) {
          case "anonymous": return loginAnonymous()
          default: {}
          }
      }
    }
    
  6. Now that handleAnonymousLogin no longer exists in your code, you need to change existing calls to it. Scroll down in StitchAuth.js until you find the authInfo function. In the line beginning with “actions”, change handleAnonymousLogin to handleLogin. The result should look like this:

    actions: { handleLogin, handleLogout },
    
  7. You now need to alter the “Anonymous Login” button to call handleLogin when clicked, instead of handleAnonymousLogin. Modify the onClick handler as follows:

    <LoginButton provider="anonymous" onClick={() => actions.handleLogin("anonymous")}>
    

At this point, your anonymous login should work exactly as it did before. Now you’re ready to add login functionality for other authentication providers.

2

Add Facebook OAuth Functions

Your next step in adding Facebook OAuth functionality is to write a loginFacebook function. The main difference between loginAnonymous and the loginFacebook function that you are about to write is the use of loginWithCredential vs loginWithRedirect. Some types of authentication, like Anonymous, use loginWithCredential, which means that it uses a regular Stitch credential to authenticate the user. The Facebook OAuth provider, on the other hand, redirects the user away from the current page to a page owned by Facebook where the user authenticates. Upon successful authentication, Facebook returns the user to the original page with a token that proves their identity. The Stitch SDK uses the token to construct a redirect credential and log the user in.

  1. Before you can invoke loginWithRedirect in the loginFacebook function, you must add FacebookRedirectCredential to your import from mongodb-stitch-browser-sdk:

      import {
          AnonymousCredential,
          FacebookRedirectCredential
      } from "mongodb-stitch-browser-sdk";
    
  2. In the same file, add the following loginFacebook function.

    export async function loginFacebook() {
        return await app.auth.loginWithRedirect(new FacebookRedirectCredential());
    }
    
  3. Now that you’ve written your loginFacebook function, you must add it to handleLogin. Before you can do this, you must first import the function to StitchAuth.js. Add loginFacebook to your import from stitch/authentication.js

      import {
          hasLoggedInUser,
          loginAnonymous,
          loginFacebook,
          logoutCurrentUser,
          getCurrentUser,
          addAuthenticationListener,
          removeAuthenticationListener,
          handleOAuthRedirects,
      } from "./../stitch/authentication";
    
  4. Recall that handleLogin is meant to handle login across multiple auth providers. In this step, you will give the function the ability to handle login with Facebook OAuth. Navigate to StitchAuth.js, and add the following line of code within the switch statement in the handleLogin function.

    case "facebook": return loginFacebook()
    
  5. The final step is to create a button to provide the user with the option to login with Facebook. This button is similar to the anonymous login button, but when clicked, it passes "facebook" as the argument to handleLogin. Copy and paste the following React code for the Facebook login button immediately below the code for the Anonymous button:

    <LoginButton onClick={() => actions.handleLogin("facebook")}>
      Log In with Facebook
    </LoginButton>
    
3

Handle Facebook Redirects

It may seem as though you now have all pieces needed to log in with Facebook. Try running your app to see what happens. You’ll notice that when you click the “Log In with Facebook” button, you get an error. This happens because you haven’t actually handled redirects with Facebook yet. You’ll address these in the upcoming steps.

  1. The first change you need to make is in your Stitch application. In this step, you will add a redirect URI to the Stitch backend. This how you “approve” a specific URL which lets Stitch know that it’s safe to redirect back to a specific domain.

    1. Select Users from the left-side navigation.

    2. Select the Providers tab.

    3. For Facebook, click the Edit button.

    4. In the Facebook provider settings, add the following to the Redirect URIs section:

      http://localhost:3000/
      

      Note

      Port 3000 is the default port on which your app will run. However, if you notice your app is running on a different port, update the port number in the above URI accordingly.

    Deploy Your Changes

    Again, make sure to Review and Deploy Changes to your Stitch app by clicking either the button in the blue bar at the top of the screen, or the Deploy button in the left sidebar.

  2. Although the loginFacebook function uses redirect credentials, your app currently has no way of knowing when an external login has redirected the user back to the app, and thus, does not actually log the user into the app. In this step, you will add the handleOAuthRedirects function, which checks that the user has returned to the app, and then completes the OAuth login. Copy the function below into stitch/authentication.js.

    export function handleOAuthRedirects() {
        if (app.auth.hasRedirectResult()) {
            return app.auth.handleRedirectResult();
        }
    };
    
  3. Import handleOAuthRedirects for use in your StitchAuth.js file. Add the highlighted line to your import from stitch/authentication.js:

    import {
        hasLoggedInUser,
        loginAnonymous,
        loginFacebook,
        logoutCurrentUser,
        getCurrentUser,
        addAuthenticationListener,
        removeAuthenticationListener,
        handleOAuthRedirects,
    } from "./../stitch/authentication";
    
  4. Finally, in StitchAuth.js, add a call to handleOAuthRedirects right after the call to addAuthenticationListener within the effect hook.

      useEffect(() => {
          const authListener = {
              //existing code
          };
          addAuthenticationListener(authListener);
          handleOAuthRedirects();
          setAuthState(state => ({ ...state}));
          return () => {
              removeAuthenticationListener(authListener);
          };
      }, []);
    

C. Build and Test

You can now run the app. You will see the login screen with the newly-added Facebook button.

Log in, add some items to your To-do list, and then log out. When you log in again with the same account, your to-do list is shown. In addition, if you log on from other client apps that use the same Facebook application, you can see your to-do list and items there.

Summary

Congratulations! You now have a working to-do app that includes Facebook authentication.