How do I build a functionality that works both for mobile and web?

First Published: 26 April 2018
Updated on: 24 September 2018

Today you’ll learn how to build functionalities that need native plugins but also work for the web. It’s going to be a short read, but I felt like writing it because a few people have asked me that question over email.

This article uses Cordova, I strongly recommend using Capacitor since it can be a bridge between native and web APIs.

First, let me explain what I mean by functionality that works in both places. I mean, a feature that needs a native plugin when the app runs installed but that has a Web API for when you deploy as a PWA.

In this example, we’ll use Google Sign-In. When you want to use it on an installed app, you need to install the google-plus plugin and follow the native flow.

When you use it on the web you don’t need any of that; you can use the web API for it.

For example, when you want to run the native functionality, you’ll do something like this:

async googleSignIn() {
    const googleLogin = await this.googlePlus.login({
        webClientId: firebaseSdkConfig.webClientId,
        offline: true,
    });

    const credential: AuthCredential = firebase.auth.GoogleAuthProvider.credential(
        googleLogin.idToken
    );

    return this.afAuth.auth.signInWithCredential(credential);
}

That code signs up your new user with Google when the app is installed as a native app on the phone but will error out when you’re running through a browser because Cordova is not available.

The web implementation would look something like this:

async googleSignIn() {
    const provider: GoogleAuthProvider = new firebase.auth.GoogleAuthProvider();
    return firebase.auth().signInWithPopup(provider);
}

Now the is, how do I tell my app to use one when we’re in web and another one when we’re running as an installed app?

And the most straightforward solution I found was to ask the app using the Platform plugin.

if (this.platform.is('cordova')) {
}

The full example would look something like this:

async googleSignIn() {
    if (this.platform.is('cordova')) {
        const googleLogin = await this.googlePlus.login({
          webClientId: firebaseSdkConfig.webClientId,
          offline: true,
        });

        const credential: AuthCredential = firebase.auth.GoogleAuthProvider.credential(
          googleLogin.idToken
        );

        return this.afAuth.auth.signInWithCredential(credential);

    } else {
        const provider: GoogleAuthProvider = new firebase.auth.GoogleAuthProvider();
        return firebase.auth().signInWithPopup(provider);
    }
  }

Go ahead, try it out and do let me know how it works for you, remember, you need to import and inject all the providers we’re using in the constructor.

If you have a moment, please let me know how you’ll use this, leave a comment below and let me know which plugin you’re trying to get to work on both mobile and web.

If you want to take a deeper dive on Ionic + Firestore you should go through my FREE course: Build your first Firestore powered Ionic app.