Real-time Remote Config on iOS

Rita Zerrizuela
iguanafix-engineering
5 min readJan 2, 2019

--

What to do when you need to roll out Remote Config changes quickly? Maybe the last changes you made didn’t work out and you want to undo them ASAP. Or something went wrong in your app and you need to disable an entire feature.

Calling fetchWithExpirationDuration:completionHandler: more often (with a lower expiration duration) is one way to go, but it's discouraged by Firebase. And you run the risk of getting throttled.

What if you could invalidate the Remote Config cache on demand, without having to hardcode a short expiration duration? Instead of repeatedly asking the server for updates, have the server notify you when there are changes. Firebase Remote Config now integrates with Cloud Functions, so it’s possible to trigger executions when the config gets published or rolled back. This means you can have a function send a silent push notification to your app to let it know the configuration changed.

Real-time Remote Config updates is about using a push notification to invalidate the Remote Config cache

A silent push notification won’t be displayed to the user while still triggering a callback in the AppDelegate. You can even get iOS to launch your app in the background (or resume it) when the push notification arrives, by including the option content_available set to true. One gotcha: iOS won't launch your app in the background if the user manually killed it. This lasts until the next reboot (after the first unlock). So other than that, you're golden.

Implementation

The process boils down to this:

  1. Subscribe the app to a Firebase Cloud Messaging topic
  2. Create a Cloud Function that triggers when the Remote Config changes
  3. Handle the silent push notification in the AppDelegate
  4. Invalidate the Remote Config cache on the next launch

How to set up Firebase Cloud Messaging is out of the scope of this article, but the docs are a great place to start.

1. Subscribe to a topic

Once the push notifications are up and running, we’ll need to subscribe the app to a topic. We’ll use one specifically for Remote Config purposes.

2. Create a Cloud Function

A Cloud Function is just a Node.js script, so you’ll need Node.js on your machine. At the time of this writing Cloud Functions supports either Node v6 or Node v8, with v6 being the default.

Once you have Node.js, start by installing the Firebase CLI.

npm install -g firebase-tools

Then authenticate with the CLI tool.

firebase login

Now create a folder for the functions, cd into it and initialize the Firebase project.

firebase init functions

This will start a CLI wizard. Complete it and you’ll be ready to go.

Time to add the Cloud Function that will send a silent push notification to the REMOTE_CONFIG channel. Inside the functions directory of your newly created project you'll find index.js. Open it and replace the contents with the following:

We’re using the notification to deliver a payload with the key CONFIG_STATE. That will signal to your app that the Remote Config data has changed. The option content_available is necessary to get iOS to resume the app or launch it in the background, if necessary.

Now that the function is in place, we can deploy it to Firebase so it’s ready to run.

firebase deploy --only functions

That will deploy to the Firebase project selected in firebase init functions. To deploy to another project, add it first with firebase use --add. Once added you can switch projects running firebase use my-project-alias.

3. Handle the push notifications

We need to implement the method application:didReceiveRemoteNotification:fetchCompletionHandler: in the AppDelegate to handle the incoming push notifications. If the userInfo dictionary has the key CONFIG_STATE (the one we added to the notification payload) then it's the notification we're looking for.

Here it’s tempting to just call fetchWithExpirationDuration:completionHandler: with a very low expiration duration to retrieve the updated values right then and there. But doing so will make all the notified app instances request fresh values at roughly the same time. That will most likely get the app throttled, so we'll defer it to the next launch instead.

4. Invalidate the Remote Config cache

We just need to save a flag to UserDefaults and check it right before fetching Remote Config values.

If the config is outdated, we’ll bypass the cache by setting the expiration duration to 0. This will force a one-time full reload without having to wait for the cache to expire.

That’s all the setup. Now go to the Remote Config panel and publish a change. Then check out the Functions tab. It should look like the following:

The log should register a successful execution:

TL;DR

A way to avoid polling the Firebase server for Remote Config updates is to have a Cloud Function send your app a silent push notification whenever changes are published. Then the app can invalidate the Remote Config cache and request fresh values on the next launch. Beware, though, that the users who manually closed the app won’t get these push notifications until they reboot and unlock their phones.

Enjoyed this article? Follow us and stay tuned for more.

--

--