Expanding Authentication Options: Enabling Facebook API Provider for Login Page with Firebase Authentication (Part 10) in Your Angular-15 Ionic-7 App

Welcome back to my blog series on building my first Angular-15 Ionic-7 app! In this tenth part, I will show you how to add a Facebook API provider to the login page using Firebase authentication. This will allow users to sign in with their Facebook accounts and access the app's features.

Firebase authentication is a powerful and easy-to-use service that handles user authentication and authorization for your app. Facebook API provider is one of the many social login options that Firebase supports. By integrating Facebook API provider, you can leverage the popularity and reach of Facebook to attract more users to your app.

In this blog post, I will walk you through the steps of setting up the Facebook API provider, configuring Firebase authentication, and adding the login button to the login page. Let's get started!

Till now, I have used the authentication by Google and the standard email-password combination. But now, I will implement login via Facebook that will allow users to sign into the application using their existing Facebook account.

First, I begin by creating a developer account on:

Meta for Developers

After, this I will create a new app on my developer console to begin app configuration (choose type: consumer app) on the ‘My Apps’ page as demonstrated in Figure 36 as follows:

Figure 36: Meta developer console with my app listed

Before using the App ID from this console, I will change some of the basic settings in this app. I will enter the app’s Bundle ID in the iOS configurations which is mentioned in the capacitor.config file in my application. In the Android settings, I needed to add the hash key which took me a long time to figure out because I had to download OpenSSL and other files, and locate them to get the key. I have used the below instructions to retrieve the hash key from command prompt in Windows system:

//! run this command in your cmd prompt to get the hash key for facebook login
  //keytool -exportcert -alias androiddebugkey -keystore "C:\\Users\\ADMIN\\.android\\debug.keystore" | "C:\\Program Files\\OpenSSL-Win64\\bin\\openssl" sha1 -binary | "C:\\Program Files\\Git\\usr\\bin\\base64.exe"
  //remember to download the openssl from the internet and add it to your environment variables
  //the hash key will be displayed in the cmd prompt
  // the hash key is used to configure the facebook login in the facebook developer console for your app to work properly on android devices

Next, I will copy the App ID and App secret from the app’s basic settings which is demonstrated in Figure 37:

Figure 37: Meta app’s basic settings with App ID and App Secret

Next, I will go to my firebase console and enable Facebook as login provider under the sign-in methods. It will ask me for the App ID and the App secret which I will paste from the meta developer console. This is demonstrated in Figure 38:

Figure 38: Enable Facebook as service provider on firebase console

Next, I will copy the OAuth redirect URI and add it to the Facebook Login Settings on the meta developer console which took me a little bit of digging. This is demonstrated in Figure 39:

Figure 39: Add OAuth Redirect URI from Firebase in Meta developer console

Once this setup is done, I will go back to my VS code editor and use the Facebook authentication provider by the Firebase authentication package installed previously in auth.service.ts file:

import {
  Auth,
  signInWithPopup,
  signOut,
} from '@angular/fire/auth';

import { FacebookAuthProvider } from 'firebase/auth';

@Injectable({
  providedIn: 'root',
})
export class AuthService {
  constructor(private auth: Auth) {} //inject the auth service

  async firebaseLoginWithFacebook() {
    const provider = new FacebookAuthProvider();
    const user = await signInWithPopup(this.auth, provider);
    // console.log(user);
    return user;
  }
  async firebaseLogoutWithFacebook() {
    const user = await signOut(this.auth);
    // console.log(user);
    return user;
  }
}

The above code defines an Angular service AuthService that provides methods for logging in and logging out of Firebase Authentication with Facebook as the identity provider. The Auth, signInWithPopup, and signOut functions are imported from the @angular/fire/auth module, which is part of the AngularFire library for Firebase integration with Angular. The FacebookAuthProvider is imported from the firebase/auth module, which is part of the Firebase SDK for web. In the constructor method, the auth object is injected into the AuthService instance.

The firebaseLoginWithFacebook method initializes a new instance of FacebookAuthProvider, and then calls the signInWithPopup method of the injected auth object, passing in the FacebookAuthProvider instance as an argument. This prompts the user to authenticate with Facebook and returns a user credential object.

The firebaseLogoutWithFacebook method calls the signOut method of the injected auth object, which logs out the currently authenticated user and returns a promise that resolves when the operation is complete.

Overall, this code provides a simple interface for authenticating with Facebook using Firebase Authentication and provides a way to log out of the current user session.

I have referred the official Firebase documentation to get this feature:

Authenticate Using Facebook Login with JavaScript  |  Firebase

Next, I will use this service within the previously created login.page.ts file to create the logic for Facebook login and logout in the following way:

import { AuthService } from 'src/app/services/auth.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss'],
  standalone: true,
  imports: [IonicModule, CommonModule, FormsModule, ReactiveFormsModule],
})
export class LoginPage implements OnInit {
  public progress = 0;
  fbUser: any = null; // the facebook user object that will be returned from the facebook login plugin
  token: any; // the facebook token that will be returned from the facebook login plugin
  
  constructor(
    private router: Router,
    private authService: AuthService,
    private toastCtrl: ToastController
  ) { }

  async facebookLogin() {
    const user = await this.authService.firebaseLoginWithFacebook(); // login the user with facebook using the firebase login with facebook method in the auth service

    if (user) {
      this.fbUser = user; // set the fbUser to the user returned from the firebase login with facebook method in the auth service
      // console.log(this.fbUser); // log the fbUser to the console

      // display a progress bar for 5 seconds
      setInterval(() => {
        this.progress += 0.01;
        // Reset the progress bar when it reaches 100%
        // to continuously show the demo
        if (this.progress > 1) {
          setTimeout(() => {
            this.progress = 0;
          }, 1000);
        }
      }, 50);

      setTimeout(() => {
        this.router.navigateByUrl('/tabs/tab4', { replaceUrl: true });
      }, 5000);
      //display a toast message to the user
      const toast = await this.toastCtrl.create({
        message: 'You are signed in with Facebook.',
        duration: 3000,
        position: 'bottom',
      });
      await toast.present();
    }
  }

  async facebookLogout() {
    await this.authService.firebaseLogoutWithFacebook(); // logout of firebase using the firebase logout with facebook method in the auth service
    this.fbUser = null; // set the fbUser to null

    //navigate to the login page
    setTimeout(() => {
      this.router.navigate(['/login']);
    }, 5000);

    //display a toast message to the user
    const toast = await this.toastCtrl.create({
      message: 'You are signed out of Facebook.',
      duration: 3000,
      position: 'bottom',
    });
    await toast.present();
  }
}

The above code defines the previously created Angular page component LoginPage that provides methods for logging in and logging out of Firebase Authentication with Facebook using the AuthService service. The progress, fbUser, and token variables are initialized to null values. In the constructor, the router, authService, and toastCtrl objects are injected.

The facebookLogin method calls the firebaseLoginWithFacebook method of the injected authService object, which initiates a Firebase authentication flow using Facebook as the identity provider. If the authentication is successful, the fbUser object is set to the returned user object, and a progress bar is displayed for 5 seconds. After that, the user is redirected to the /tabs/tab4 route which is the profile page, and a toast message is displayed to indicate that the user is signed in with Facebook.

The facebookLogout method calls the firebaseLogoutWithFacebook method of the injected authService object, which logs out the currently authenticated user. The fbUser object is then set to null, and the user is redirected to the /login route. A toast message is displayed to indicate that the user is signed out of Facebook.

Next, I will add the required login and logout buttons within the template file login.page.html that will use this functionality in the following way:

<ion-header [translucent]="false">
  <ion-toolbar>
    <ion-title>Login/Sign Up</ion-title>
    <ion-progress-bar [value]="progress"></ion-progress-bar>
    <ion-buttons slot="start">
      <ion-back-button defaultHref="/"></ion-back-button>
    </ion-buttons>
    <ion-buttons slot="end">
      <ion-menu-button menu="main-menu"></ion-menu-button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>

<ion-content [fullscreen]="true" class="ion-padding">
...
  <!-- Facebook Login -->
  <ion-card class="ion-padding">
    <ion-button
      class="ion-margin-top"
      (click)="facebookLogin()"
      expand="full"
      fill="solid"
      shape="round"
      *ngIf="!fbUser"
    >
      <ion-icon slot="start" name="logo-facebook"></ion-icon>
      Facebook Login
    </ion-button>

    <ion-button
      *ngIf="fbUser"
      (click)="facebookLogout()"
      expand="block"
      fill="outline"
      shape="round"
    >
      Facebook Logout
    </ion-button>

    <ion-item *ngIf="fbUser" lines="none">
      <ion-avatar slot="start">
        <img title="user" [src]="fbUser.user.photoURL" />
      </ion-avatar>
      <ion-label>
        <p>{{fbUser.user.displayName}}</p>
        <p>{{fbUser.user.email}}</p>
        <p>DOB: {{fbUser.user.reloadUserInfo.dateOfBirth}}</p>
      </ion-label>
    </ion-item>
  </ion-card>
</ion-content>

The above code uses the Ionic button components and *ngIf directives to display the facebook login and logout buttons with their respective click events. Next we have an Ionic item which accesses the user details from the received fbUser object and displays their name, email and date of birth if it is shared in their Facebook account. Once this set up is built, it will work in the way demonstrated in Figure 40 and 41 as follows:

Figure 40: Facebook login pop up



Figure 41: Facebook login successful with user data

Finally the Facebook login works properly for the PWA app. I also tried the Facebook Login plugin from @capacitor-community/facebook-login - npm (npmjs.com) but there were issues with depreciated plugins and mismatched dependencies.

Figure 42: Facebook user registered under users in firebase console.

Also, the external plugin doesn’t register the user within the Firebase console as demonstrated in Figure 42 which is the advantage with Firebase service providers. With this path, I was able to make the previously created authentication guard work properly. Also, there is an error which appears when if I am using the same email Id for my google account and if it already exists in the user database, the Facebook account with the similar ID just won’t register because of similar user credentials.

In this blog post, we have learned how to add Facebook API provider to our login page using firebase authentication. We have also seen how to use the Ionic-7 components and Angular-15 directives to create a user-friendly interface. By integrating Facebook API, we can allow our users to sign in with their existing Facebook accounts and access their profile information. This can improve the user experience and engagement of our app.

Stay tuned for more updates and happy coding!

Popular Posts

Perform CRUD (Create, Read, Update, Delete) Operations using PHP, MySQL and MAMP : Part 4. My First Angular-15 Ionic-7 App

Visualize Your Data: Showcasing Interactive Charts for Numerical Data using Charts JS Library (Part 23) in Your Angular-15 Ionic-7 App

How to Build a Unit Converter for Your Baking Needs with HTML, CSS & Vanilla JavaScript