Implementing OAuth 2.0 social login with Facebook: A comprehensive guide
Tags: appwrite, flutter, oauth, facebooklogin
Published: 2023-07-28 08:50:22

Open Authorization, popularly known as OAuth 2.0, is a secure and fast security mechanism that enables users to access websites and applications. Beyond the safety and ease of use, it gives users total control of the information shared with the requesting websites/applications.

In this post, we will learn how to set up OAuth 2.0 social login in a Flutter application using Facebook as the provider. The project repository can be found [here](https://github.com/Mr-Malomz/flutter_auth/tree/dev).

## Prerequisites

To fully grasp the concepts presented in this tutorial, the following are required:

-   Basic understanding of Dart and Flutter
-   Flutter [SDK](https://flutter.dev/docs/get-started/install) installed
-   [Xcode](https://developer.apple.com/xcode/) with a developer account
-   Appwrite account; [s](https://cloud.appwrite.io/register?utm_source=hackmamba&utm_medium=hackmamba-blog)[ign-up](https://cloud.appwrite.io/register?utm_source=hackmamba&utm_medium=hackmamba-blog) is completely free
-   Facebook developer account; [s](https://developers.facebook.com/)[ign-up](https://developers.facebook.com/) is completely free

## Getting started

To get started, we need to clone the project by navigating to the desired directory and running the command below:

```bash
git clone https://github.com/Mr-Malomz/flutter_auth
```

## Running the project

First, we need to install the project dependencies by running the command below:

```bash
flutter pub get
```

Then, run the project using the following command:

    flutter run

The command above will run the application on the selected device.

![Login screen](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1688676860713_Screenshot+2023-07-06+at+21.54.02.png)

## Set up a project on Appwrite

To get started, we need to log into our Appwrite console, click the **Create project** button, input `flutter_auth` as the name, and then click **Create**.

![Create project](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687518026974_Screenshot+2023-06-23+at+11.38.55.png)

**Add platform support**

To add support for our Flutter app, navigate to the **Home** menu and click the **Flutter App** button.

![Add platform](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687518039269_Screenshot+2023-06-23+at+11.39.30.png)

Next, we must modify the Flutter application as detailed below.

To obtain our Bundle ID, navigate to the path below:
**ios > Runner.xcodeproj > project.pbxproj**

Open the `project.pbxproj` file and search for `PRODUCT_BUNDLE_IDENTIFIER`.

![Select new Flutter app](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671388862700_Screenshot+2022-12-18+at+01.30.54.png)

Finally, open the project directory on [Xcode](https://developer.apple.com/xcode/), open the `Runner.xcworkspace` folder in the app's iOS folder, select the **Runner** project in the Xcode project navigator, select the **Runner** target in the primary menu sidebar, and then select **iOS 11** in the deployment info’s target.

![Change deployment target](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1688677146163_Screenshot+2023-07-06+at+21.56.26.png)

**Enable Facebook as the preferred OAuth 2.0 provider**

To do this, we need to navigate to the **Auth** menu, click the **Settings** tab, and enable `Facebook` as a provider.

![Navigate to the provider](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687518663847_Screenshot+2023-06-23+at+11.40.34.png)
![Facebook OAuth](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687519983770_Screenshot+2023-06-23+at+12.29.59.png)

We will fill in the required details later, however, we must copy and keep the redirect **URI**; it will come in handy when setting up our application on Facebook.

![Copy URI](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687519997792_Screenshot+2023-06-23+at+12.30.54.png)

## Set up Facebook OAuth 2.0

With our project partly configured on Appwrite, we also need to set up our project on the Facebook developer portal. To do this, log into the portal, navigate to the **My Apps** section, click the **Create App** button, select the **Set up Facebook Login option** and click **Next**.

![Create App](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687518748133_Screenshot+2023-06-17+at+01.15.23.png)
![Select option](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687518762574_Screenshot+2023-06-17+at+01.16.50.png)

Next, we need to input our application name, contact email, and then select **Create app**.

![Create](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687518777176_Screenshot+2023-06-17+at+01.19.39.png)

Finally, we navigate to the **Products** menu, select **Settings** under `Facebook Login`, input the redirect **URI** we copied from Appwrite earlier, and **Save changes**.

![Settings](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687519022502_Screenshot+2023-06-17+at+12.29.20.png)
![URI](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687519099168_Screenshot+2023-06-17+at+12.28.56.png)

Lastly, we need to click on the **Products** menu again, select the **QuickStart** option, and select **iOS** as the preferred platform.

![Quickstart](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687519120010_Screenshot+2023-06-17+at+01.24.32.png)
![iOS app](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687519142104_Screenshot+2023-06-17+at+01.26.55.png)

**Configuring the iOS**

After selecting the iOS option, click the **Next** button, input the `Bundle ID`, **Save**, and **Continue**.

![Step 1](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687519445427_Screenshot+2023-06-17+at+21.12.13.png)
![Step 2](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687519474168_Screenshot+2023-06-17+at+21.13.50.png)

Click **Next** on the `Enable Single Sign On for Your App` step.

![Enable Single Sign On for Your App](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687519543887_Screenshot+2023-06-17+at+21.16.24.png)

Next, we need to copy and configure our Application using the provided XML snippet.

![Copy the provided XML snippet](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687519605740_Screenshot+2023-06-17+at+01.42.41.png)

To do this, we need to modify the `info.plist` file in our source code and paste the copied snippet below the `<dict>` body tag.

We can find the file using the path below:
**ios > Runner > info.plist**

![Snippet](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687034508928_Screenshot+2023-06-17+at+21.27.04.png)

We must also update the snippet with our `Application ID`, `Client Token`, and `App name`.

We can get the required parameter as shown below:

![Application ID](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687519667472_Screenshot+2023-06-17+at+21.42.54.png)
![Client Token](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687519720733_Screenshot+2023-06-17+at+01.48.29.png)

Sample of a properly filled snippet below:

```xml
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>1232334554343456</key>
<array>
    <string>1232334554343456</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>APP-ID</string>
<key></key>
<string>1ac7fd263ettr6yeta1b807ad589rt</string>
<key>flutter_auth</key>
<string>APP-NAME</string>
```

## Putting it together on Appwrite

With our application configured on Facebook, we need to create a link to it on Appwrite. To do this, we need to first navigate to the **Basic** tab under **Settings** menu and copy the **App ID** and **App secret**.

![App ID And App secret](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1688677759237_Screenshot+2023-07-06+at+22.07.07.png)

Lastly, we need to update the Facebook provider details on Appwrite with the copied parameters and **Update**.

![Add App ID an App Secret](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1687520024254_Screenshot+2023-06-23+at+12.29.59.png)

## Integrating Facebook OAuth 2.0 with Flutter using Appwrite

With all that done, let’s build the social login into our application.

First, we need to create a class for storing our Appwrite credentials. To do this, we need to create a `utils.dart` file in the `lib` folder and add the snippet below:

```dart
class AppConstant {
  final String projectId = "REPLACE WITH PROJECT ID";
  final String endpoint = "https://cloud.appwrite.io/v1";
}
```

**PS**: _We can get our Project ID from the Appwrite console._

Second, we need to create a service file to separate the application core logic from the UI. To do this, we need to create an `auth_service.dart` file in the same `lib` folder and add the snippet below:

```dart
import 'package:appwrite/appwrite.dart';
import 'package:flutter_auth/utils.dart';

class AuthService {
  Client _client = Client();
  late Account _account;

  AuthService() {
    _init();
  }

  //initialize the application
  _init() async {
    _client
        .setEndpoint(AppConstant().endpoint)
        .setProject(AppConstant().projectId);

    _account = Account(_client);
  }

  Future loginWithFacebook() async {
    try {
      return await _account.createOAuth2Session(provider: 'facebook');
    } catch (e) {
      throw Exception('Error login into Facebook!');
    }
  }
}
```

The snippet above does the following:

-   Imports the required dependencies
-   Creates an `AuthService` class with `_client` and `_account` properties to connect to the Appwrite instance
-   Creates an `_init` method that configures Appwrite using the properties
-   Creates a `loginWithFacebook` method that uses the `_account` property to login with OAuth 2.0 using `facebook` as the provider

Lastly, we need to modify the `login.dart` file inside the `screens` folder to use the service.

```dart
import 'package:flutter/material.dart';
import 'package:flutter_auth/auth_service.dart';

class Login extends StatefulWidget {
  const Login({super.key});

  @override
  State<Login> createState() => _LoginState();
}

class _LoginState extends State<Login> {
  bool _isLoading = false;

  _loginWithFacebook() {
    setState(() {
      _isLoading = true;
    });
    AuthService()
        .loginWithFacebook()
        .then((value) => {
              setState(() {
                _isLoading = false;
              })
            })
        .catchError((e) {
      setState(() {
        _isLoading = false;
      });
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Error login into facebook!')),
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Image.asset('images/lock.png'),
            const SizedBox(height: 40.0),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 10.0),
              child: Container(
                width: double.infinity,
                height: 45.0,
                child: TextButton(
                  onPressed: _isLoading
                      ? null
                      : () {
                          _loginWithFacebook();
                        },
                  child: Text(
                    'Login with Facebook',
                    style: TextStyle(
                        fontSize: 12.0,
                        fontWeight: FontWeight.bold,
                        color: Colors.white),
                  ),
                  style: ButtonStyle(
                      backgroundColor:
                          MaterialStateProperty.all(Color(0xff3b5998)),
                      padding: MaterialStateProperty.all<EdgeInsets>(
                        const EdgeInsets.symmetric(horizontal: 15.0),
                      )),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}
```

The snippet above does the following:

-   **Lines 1-2**: Import the required dependencies
-   **Line 12**: Creates an `_isLoading`, property to manage the application state
-   **Lines 14-33**: Create a `_loginWithFacebook` method to log in users using the `AuthService().loginWithFacebook` service and set state accordingly
-   **Lines 52-56**: Update the button to use the method created

With that done, we restart the application using the code editor or run the command below:

```bash
flutter run
```

![](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExYzE2bTNvMTJnczN5b2ttYXVoZGpkc29vZ2htZHR3aHRkbXp3YTR0ciZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/rhUn04JIwecabiCKEA/giphy.gif)

**Facebook update on business verification**

Facebook recently updated its permission system for applications using OAuth 2.0. It requires the developer to do a [Business Verification](https://developers.facebook.com/docs/development/release/business-verification) to gain full access. If we decide to log in using our credentials, we will get an error about permissions, as shown below:

![Permission issue](https://paper-attachments.dropboxusercontent.com/s_C9210607DAFF6D80615947ED6BE237716E98BADEF0416B60FACF081B1CAEFB80_1688678108327_Screenshot+2023-07-06+at+22.12.36.png)

## Conclusion

This post detailed a step-by-step guide to implementing Facebook OAuth 2.0 social login in a Flutter application using [Appwrite](https://appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog). Beyond Facebook, Appwrite supports up to 35 other providers.

These resources may also be helpful:

-   [Appwrite official documentation](https://appwrite.io/docs?utm_source=hackmamba&utm_medium=hackmamba-blog)
-   [Appwrite OAuth support](https://appwrite.io/docs/authentication#oauth)
-   [Facebook developer portal](https://developers.facebook.com/)