angularfirebaseionic-frameworkfacebook-authenticationcapacitor

Ionic/Angular Capacitor plugin & firebase FB auth : FacebookLogin does not have web implementation error


Here is my "sign in" function that works perfectly on Android and allows me to use Facebook auth in myapp :

  async signIn(): Promise<void> {
    const FACEBOOK_PERMISSIONS = ['public_profile', 'email'];

    const result = await Plugins.FacebookLogin.login({ permissions: FACEBOOK_PERMISSIONS });
    if (result && result.accessToken) {
      let user = { token: result.accessToken.token, userId: result.accessToken.userId }
      let navigationExtras: NavigationExtras = {
        queryParams: {
          userinfo: JSON.stringify(user)
        }
      };
      this.router.navigate(["/feed"], navigationExtras);
    }
  }

I would like to test my app like I used to do on my browser but I got this error: Error:

core.js:4197 ERROR Error: Uncaught (in promise): FacebookLogin does not have web implementation.
at resolvePromise (VM1677 polyfills.js:3904)
at VM1677 polyfills.js:3811
at rejected (VM1678 vendor.js:113087)
at ZoneDelegate.invoke (VM1677 polyfills.js:3470)
at Object.onInvoke (VM1678 vendor.js:62348)
at ZoneDelegate.invoke (VM1677 polyfills.js:3469)
at Zone.run (VM1677 polyfills.js:3229)
at VM1677 polyfills.js:3963
at ZoneDelegate.invokeTask (VM1677 polyfills.js:3505)
at Object.onInvokeTask (VM1678 vendor.js:62336)

I tried to register my capacitor plugin using

import { registerWebPlugin } from '@capacitor/core';

registerWebPlugin(FacebookLogin);

But this is not working at all and this is the only solution I found via google search.


Solution

  • Simon at Devdactic.com put together a great tutorial about Ionic Facebook Login with Capacitor. There are a few things that need to be setup to get the web implementation to work properly.

    1. Load the Facebook SDK
    2. Register the Facebook web plugin with Capacitor
    3. Setup a switch to determine which version of the Facebook login to use based on the platform the app is running on.

    In index.html add in JavaScript to initialize the Facebook SDK. Add this script tag after the body tag

    <script>
      window.fbAsyncInit = function () {
        FB.init({
          appId: '#YOUR_APP_ID_HERE#',
          cookie: true, // enable cookies to allow the server to access the session
          xfbml: true, // parse social plugins on this page
          version: 'v5.0' // use graph api current version
        });
      };
    
      // Load the SDK asynchronously
      (function (d, s, id) {
        var js, fjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) return;
        js = d.createElement(s); js.id = id;
        js.src = "https://connect.facebook.net/en_US/sdk.js";
        fjs.parentNode.insertBefore(js, fjs);
      }(document, 'script', 'facebook-jssdk'));
    </script>
    

    Next (step 2 & 3) register the FacebookLogin as a Web Plugin to Capacitor and setup the switch

    import { Component } from '@angular/core';
    import { FacebookLoginPlugin } from '@capacitor-community/facebook-login';
    import { Plugins, registerWebPlugin } from '@capacitor/core';
    import { isPlatform } from '@ionic/angular';
    import { HttpClient } from '@angular/common/http';
    
    import { FacebookLogin } from '@capacitor-community/facebook-login';
    registerWebPlugin(FacebookLogin);
    
    @Component({
      selector: 'app-login',
      templateUrl: './login.page.html',
      styleUrls: ['./login.page.scss'],
    })
    export class LoginPage {
      fbLogin: FacebookLoginPlugin;
      user = null;
      token = null;
     
      constructor(private http: HttpClient) {
        this.setupFbLogin();
      }
     
      async setupFbLogin() {
        if (isPlatform('desktop')) {
          this.fbLogin = FacebookLogin;
        } else {
          // Use the native implementation inside a real app!
          const { FacebookLogin } = Plugins;
          this.fbLogin = FacebookLogin;
        } 
      }
     
      async login() {
        const FACEBOOK_PERMISSIONS = ['email', 'user_birthday'];
        const result = await this.fbLogin.login({ permissions: FACEBOOK_PERMISSIONS });
     
        if (result.accessToken && result.accessToken.userId) {
          this.token = result.accessToken;
          this.loadUserData();
        } else if (result.accessToken && !result.accessToken.userId) {
          // Web only gets the token but not the user ID
          // Directly call get token to retrieve it now
          this.getCurrentToken();
        } else {
          // Login failed
        }
      }
     
      async getCurrentToken() {    
        const result = await this.fbLogin.getCurrentAccessToken();
     
        if (result.accessToken) {
          this.token = result.accessToken;
          this.loadUserData();
        } else {
          // Not logged in.
        }
      }
     
      async loadUserData() {
        const url = `https://graph.facebook.com/${this.token.userId}?fields=id,name,picture.width(720),birthday,email&access_token=${this.token.token}`;
        this.http.get(url).subscribe(res => {
          this.user = res;
        });
      }
     
      async logout() {
        await this.fbLogin.logout();
        this.user = null;
        this.token = null;
      }
    }