Skip to content

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

Seifeddine October 29, 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 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 ScanbotBarcodeScannerSDK 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. Download the default values for Firebase
  5. Create a new iOS project
  6. Fetch and apply the default values to the Barcode Scanner SDK
  7. Test the Remote Config

Requirements

We’ll use Xcode to create a new iOS application. For this, we’ll need:

  • A machine running a recent version of macOS
  • Xcode
  • A Google account registered in Firebase

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).

Now give the project a name:

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

We’ll use the default selection and proceed.

And with that, the project is 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.

Then click on 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.

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.

Firebase Console will remind you that you need to publish the changes. Let’s do that so we can use the property in our iOS 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 iOS app to it. To do so, click on the iOS icon below the project name.

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

For 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 GoogleService-Info.plist.

Afterward, click on Next.

We now need to add the Firebase SDK. We will use the Swift Package Manager version.

Afterward, click on Next.

The initialization code is available for SwiftUI, Swift, and Objective-C. For this tutorial, we will use Swift.

We will use this code after creating our app in Step 5.

We are all set, so we can continue to Step 4.

Step 4: Downloading the default values for Firebase Remote Config

Now we need to download the default values for our Remote Config so our app knows which values it should use until the connection with Firebase Remote Config is set up.

To do this, open up the Firebase Console again, go to your project, and select Run > Remote Config once more.

Select the property and click on the three dots next to it. Choose the Download default values option.

As a format, choose .plist for iOS and click on Download file:

Step 5: Creating a new iOS project

Open Xcode and create a new project.

We’ll set up the project to use our Barcode Scanner SDK by following the setup guide from our docs:

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

First, let’s put the file we downloaded earlier (GoogleService-Info.plist) into the app folder, just as we were told when downloading the config file.

Next, we need to add the Firebase SDK to our project:

Now go to AppDelegate.swift and add this code:

Finally, place the PLIST file we downloaded earlier (remote_config_defaults.plist) in the same place as our GoogleService-Info.plist to be used later.

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

The initialization of our SDK happens in the AppDelegate class. Instead of calling Scanbot.setLicense(“YOUR_LICENSE_KEY”), we will create a class responsible for initiliazing our SDK from Firebase.

Create the following class:

struct LicenseKeyEntity: Decodable {
    let licenseKey: String

    enum CodingKeys: String, CodingKey {
        case licenseKey = "license_key"
    }

    init(from decoder: any Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.licenseKey = try container.decode(String.self, forKey: .licenseKey)
    }
}

This will be used when decoding our value from Firebase.

Then, create a singleton class responsible for initializing our SDK:

import ScanbotBarcodeScannerSDK
import FirebaseRemoteConfig

class ScanbotInitialization {

    static var shared = ScanbotInitialization()

    private let remoteConfig: RemoteConfig

    /// Here we specify that the Remote Config shouldn’t be requested any more often than 
    /// once per hour (3600 seconds) and also specify that the default values should be taken
    /// from the PLIST file we downloaded earlier `remote_config_defaults.plist` and placed in
    /// the project.
    /// This way, the default values will be used until the Firebase Remote Config first fetches 
    /// the data from the server.

    /// Still, make sure to update the license key in the default values and update the file in 
    /// the build when you’ve received a new license key from Scanbot SDK for extending your 
    /// license.
    private init() {
        remoteConfig = RemoteConfig.remoteConfig()
        let settings = RemoteConfigSettings()
        settings.minimumFetchInterval = 3600
        remoteConfig.configSettings = settings

        remoteConfig.setDefaults(fromPlist: "remote_config_defaults")
    }

    /// With this, the app requests the update of the Firebase Remote Config and activates it.
    /// When we access the value from Remote Config, we will get the value received from 
    /// the server.
    private func fetchFirebaseValues() {
        remoteConfig.fetchAndActivate()
    }

    /// Here we access the Remote Config configuration and take the data value from the JSON.
    /// Then we pass this data to our decoder using our entity `LicenseKeyEntity`.
    /// After getting the license key value, we pass it to the scanbot initializer class.
    /// Until the remote values are loaded, the app will use the defaults we provided in 
    /// the PLIST file earlier.
    func activateScanbotSDK() {
        fetchFirebaseValues()
        remoteConfig.ensureInitialized { error in
            if let error {
                print("Error fetching remote config values: \(error)")
            } else {
                do {
                    let json = self.remoteConfig.configValue(forKey: "scanbot_license_key").dataValue
                    let decodedLicense = try JSONDecoder().decode(LicenseKeyEntity.self, from: json)
                    print("ScanbotFirebaseExample, License key: \(decodedLicense.licenseKey)")
                    let success = Scanbot.setLicense(decodedLicense.licenseKey)
                    print("ScanbotFirebaseExample, Scanbot Barcode SDK initialized: \(success)")
                } catch (let error) {
                    print("Error when decoding LicenseKeyEntity: \(error.localizedDescription)")
                }
            }
        }
    }
}

One more important thing to mention is that if you followed our SDK initialization instructions, you need to change the function accordingly:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    FirebaseApp.configure()

    ScanbotInitialization.shared.activateScanbotSDK()

    return true
}

The complete AppDelegate class will look like this:

import UIKit
import FirebaseCore

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        FirebaseApp.configure()

        ScanbotInitialization.shared.activateScanbotSDK()

        return true
    }

    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }


}

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

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

Step 7: Testing the Remote Config

Finally, it’s time to test what happens if we 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.

In the next dialog, click on Save again and publish the 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 in the app:

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.

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

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 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 module 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 User Defaults, 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 run 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!