How to use Firebase Remote Config to automatically update the Scanbot SDK license key – Capacitor guide

Marko October 10, 2024 10 mins read
app store

The Scanbot SDK works completely offline and never connects to the internet. This ensures that no third party can gain access to the data you scan and also allows you to use the scanner in locations without internet access.

However, this also means that the license key for your app cannot be updated automatically. Instead, you need to change it in the app binaries, which usually means publishing a new version of the app to Google Play or the App Store.

To solve this and help streamline the process, you can store the license key on your remote server. Or you can get it via a Firebase Remote Config property.

In this article, we’ll explore the latter option, since many developers have Firebase Analytics or Remote Config already integrated into their applications. To demonstrate how to use this technology to automatically update your license key, we’ll show you the complete integration process for our Capacitor Barcode Scanner SDK using the following steps:

  1. Set up a new Firebase project
  2. Prepare the Remote Config property
  3. Register your app in the Firebase project
  4. Create a new Capacitor project with Firebase and the Barcode Scanner SDK
  5. Fetch and apply the values to the Barcode Scanner SDK
  6. Test the Remote Config

Requirements

  • A machine running a recent version of macOS, Windows, or Linux
  • A Google account registered in Firebase
  • A local Capacitor and Ionic CLI environment set up

Step 1: Setting up a new Firebase project

Open the Firebase Console and click on Get Started with a Firebase project (or Create a project if you’ve used Firebase before).

Firebase Project Setup

Now give the project a name:

Name your project

In the next step, we need to enable Google Analytics in our project because Remote Config is part of Google Analytics’ feature set.

Enable Google Analytics

We’ll use the default selection and proceed.

Proceed

And with that, the project is ready!

Project Ready

Step 2: Preparing the Remote Config property

Now we’re ready to set up the license key property in the Remote Config.

Select Run > Remote Config.

Remote Config

Then click on Create configuration.

Create Configuration

The next step is very important and involves setting up our project’s first property:

Since the Scanbot SDK’s license key contains some special characters, we can’t just use the data type String – instead, we need to switch to JSON.

Also, remember the property name used here. We’ll use scanbot_license_key for this guide.

Next, click on the double-ended arrow to set up the default value.

Setup Default Value

Now we need to enter the license key in a JSON format.

You can use the following JSON as a property, but don’t forget to replace <ENTER_YOUR_LICENSE_KEY_HERE> with your actual license key. If you aren’t a customer yet and need a trial license key for your project, you can get one here.

{
  "license_key": "<ENTER_YOUR_LICENSE_KEY_HERE>"
}

Now you just need to hit Save.

Save Configuration

Firebase Console will remind you that you need to publish the changes. Let’s do that, so we can use the property in our Android app.

Step 3: Registering our app in the Firebase project

Now you’ll see the Firebase Console for your newly created project. Let’s add our Android and iOS app to it.

Android

First click on the Android icon below the project name.

Add Android App

We need to specify the application ID. In a real-life scenario, enter your own project’s application ID.

For the purposes of this guide, we’ll use io.scanbot.example.remoteconfig

After clicking on Register app, we can download a configuration file that Firebase prepared for us by clicking on Download google-services.json.

Afterward, click on Next.

Download Configuration

And we’re all set! Click on Continue to console.

Continue to Console

iOS

The steps for setting up iOS are similar. We start by clicking the iOS icon below the project name.

We need to specify the bundle ID. In a real-life scenario, enter your own project’s bundle ID.

For the purposes of this guide, we’ll use the same ID as Android io.scanbot.example.remoteconfig

After clicking on Register app, we can download a configuration file that Firebase prepared for us by clicking on Download GoogleService-Info.plist.

Adding Firebase to your Apple app

Afterward, click on Next.

And we’re all set! Click on Continue to console.

Step 4: Creating a new Capacitor project with Firebase and Barcode Scanner SDK

To create a Capacitor with Ionic project using the CLI, run the following command in the terminal:

ionic start CapacitorFirebase blank --capacitor --type angular-standalone --package-id io.scanbot.example.remoteconfig

This command will create a blank project with some recommended Capacitor dependencies. Please make sure that the package ID is the same as the application/bundle ID associated with your license.

We’ll set up the project to use our Barcode Scanner SDK by following our integration tutorial.

Add Firebase to your project

Now we’re ready to set up Firebase in our project.

First, let’s put the config files we downloaded earlier (google-services.json and GoogleService-Info.plist) into our project.

For Android, move your config file into the module (app-level) root directory (/android/app/) of your project.

For iOS, move your config file into the App root directory of your project (/ios/App/App/), open the App.xcodeproj with XCode, and drag the GoogleService-Info.plist file into the Xcode file explorer, into the /App/App folder.

Drag and drop GoogleService-Info.plist in XCode project

Now we need to install the @capacitor-firebase/remote-config package:

npm install @capacitor-firebase/remote-config firebase

Step 6: Fetching and applying the Remote Config values to the Barcode Scanner SDK

All that’s left is to initialize the Capacitor Barcode Scanner SDK with the license key from Firebase Remote Config.

Ideally, initialization should be done once, as soon as the app is fully launched. In our example, we’re going to fetch the remote config and initialize the SDK inside an ngOnInit callback in src/app/app.component.ts.

export class AppComponent implements OnInit {
  constructor() { }

  async ngOnInit() {
    await this.fetchAndActivateFirebaseConfig();
    const license = await this.getLicenseFromConfigOrDefault();
    await this.initializeScanbotSdk(license)
  }
}

Now let’s implement these functions one by one. Let’s start from fetchAndActivateFirebaseConfig:

private async fetchAndActivateFirebaseConfig() {
  try {
    await FirebaseRemoteConfig.fetchConfig({
      minimumFetchIntervalInSeconds: 3600,
    });

    await FirebaseRemoteConfig.activate();
  } catch (e: any) {
    console.error(e.message);
  }
}

First, we fetch the Remote Config from the server and specify that the Remote Config shouldn’t be requested any more often than once per hour (3600 seconds).

Right after fetching, we activate the fetched Remote Config, which means that when we access the value from Remote Config, we will get the value received from the server.

Now we can get the value received from the server:

private async getLicenseFromConfigOrDefault(): Promise<string> {
  try {
    const licenseKeyObject = await FirebaseRemoteConfig.getString({ key: 'scanbot_license_key' });

    return licenseKeyObject.value ? JSON.parse(licenseKeyObject.value)['license_key'] : this.defaultLicense
  } catch (e: any) {
    console.error(e.message);
    return this.defaultLicense;
  }
}

If the Remote Config can’t be fetched and activated (e.g, if the device is not connected to internet when first running the app), the licence value won’t be available and we need to have a default license value as a fallback. Once the Remote Config is fetched and activated, we’re sure that the last fetched value will be available from now on and the fallback value won’t be used anymore.

We’re now ready to initialize the Scanbot SDK:

private async initializeScanbotSdk(license: string) {
  try {
    console.log(`License key: ${license}`)

    const result = await ScanbotBarcodeSDK.initializeSdk({
      licenseKey: license
    });

    // Log the initialization info
    console.log(result.data);
  } catch (e: any) {
    console.error(`Scanbot SDK IS NOT initialized: ${e.message}`);
  }
}

Our final src/app/app.component.ts file should look like this:

import { Component, OnInit } from '@angular/core';
import { IonApp, IonRouterOutlet } from '@ionic/angular/standalone';
import { FirebaseRemoteConfig } from '@capacitor-firebase/remote-config';

import { ScanbotBarcodeSDK } from 'capacitor-plugin-scanbot-barcode-scanner-sdk'

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  standalone: true,
  imports: [IonApp, IonRouterOutlet],
})
export class AppComponent implements OnInit {
  constructor() { }

  // Set the default license if for any reason the Remote Config is never fetched and activated
  private readonly defaultLicense = '';

  async ngOnInit() {
    await this.fetchAndActivateFirebaseConfig();
    const license = await this.getLicenseFromConfigOrDefault();
    await this.initializeScanbotSdk(license)
  }

  private async fetchAndActivateFirebaseConfig() {
    try {
      await FirebaseRemoteConfig.fetchConfig({
        minimumFetchIntervalInSeconds: 3600,
      });

      await FirebaseRemoteConfig.activate();
    } catch (e: any) {
      console.error(e.message);
    }
  }

  private async getLicenseFromConfigOrDefault(): Promise<string> {
    try {
      const licenseKeyObject = await FirebaseRemoteConfig.getString({ key: 'scanbot_license_key' });

      return licenseKeyObject.value ? JSON.parse(licenseKeyObject.value)['license_key'] : this.defaultLicense
    } catch (e: any) {
      console.error(e.message);
      return this.defaultLicense;
    }
  }

  private async initializeScanbotSdk(license: string) {
    try {
      console.log(`License key: ${license}`)

      const result = await ScanbotBarcodeSDK.initializeSdk({
        licenseKey: license
      });

      // Log the initialization info
      console.log(result.data);
    } catch (e: any) {
      console.error(`Scanbot SDK IS NOT initialized: ${e.message}`);
    }
  }
}

Now our project is ready, and we can build and start the app to check if the config is applied.

First build and sync the app with:

npm run build
npx cap sync

To run on it on Android, use:

npx cap run android

To run it on iOS:

npx cap run ios

💡 To run the app on an actual iOS device, you need to adjust the Provisioning and Signing settings. Open ios/App/App.xcworkspace with Xcode, manage the signing and provisioning settings, and run the project from Xcode or with npx cap run ios.

By looking at Logcat, we can see that the license property is fetched and the SDK is initialized.

Logcat

Step 7: Testing the Remote Config

Finally, it’s time to test what happens if we actually change the value on the server. Let’s return to the Firebase Console and edit our property’s default value.

For testing purposes, we will set the value to random_value and hit Save.

Edit Default Value

In the next dialog, click on Save again and publish the changes.

Publish Changes

The update is now live. Since we’ve set up our app to not request updates more often than once per hour, it might take some time until the value is applied in the app. For testing purposes, we can also set minimumFetchIntervalInSeconds to 1.

Let’s see if the value is now applied after restarting the app:

Check Logcat

Yes! We see that the value from the Remote Config is now “random_value”. Since that’s not a valid license key, the Scanbot SDK reports that the license key is corrupted.

💡 For instructions on how to implement a listener for the license value change that will update the license immediately (not just after an app restart), check out the addConfigUpdateListener method.

Let’s change it back to the real license key and see if the license check is working correctly again.

Check License Key

Great! As we can see, the license key is now coming not from the default values but from the Firebase Remote Config servers and is applied correctly. That means that from now on, we can update the license key in the app without publishing a new build to Google Play or the App Store, which can help you save a lot of time and effort in the long run.

Although Firebase Remote Config is the easiest way to achieve this, it does come with some disadvantages. The biggest one is that if you use Firebase Remote Config, you have to include the whole Firebase/Google Analytics package in your app. This has implications for complying with data privacy regulations like the GDPR since this gives Google access to some meta information of your users.

An alternative solution would be to store the license key on your web server, accessing it via an API and then storing it in Shared Preferences, though this can be a much more complicated process. That’s why many developers prefer the Firebase Remote Config method.

Conclusion

We hope this guide on how to do license checks using Firebase Remote Config was helpful to you!

If you have questions about this guide or ran into any issues, we’re happy to help! Just shoot us an email via tutorial-support@scanbot.io. And keep an eye on this blog for more guides and tutorials!