Exploring Firebase: Running Cloud Functions Emulator on iOS Device

I recently wrote some server-side code for the app I am working on, and Cloud Functions seemed to be the easiest to begin with. We considered it as we were already using Firebase in the app. After deploying the first version quickly, I realised I was naive regarding backend development and already had to version for the next feature.

As a responsible developer, I wanted to avoid deploying directly on production and tried to find ways to test the new endpoints locally and on the iOS client side. Then, I learned about the Cloud Functions emulator, which can emulate HTTPS functions locally to test them before deploying them to production!

After some wrestling and hours wasted, I figured out how to work with the emulator on a real iOS device.

Setting Up

First, make sure you have your Firebase environment set up locally. You switch to the functions directory and run npm install. This step ensures that all the Node.js dependencies are in place.

Optionally, you can get the Firebase functions configuration by running firebase functions:config:get > .runtimeconfig.json. This grabs the configuration and stores it locally.

Configuration Magic

This is the part where I fumbled. You must fiddle with the numbers to make your iOS device play well with the local emulator.

You need your Mac's IP address instead of localhost.

Replace the localhost address that the emulator provides you with the IP address. For example, the endpoint that the emulator stated is something like this:

http://127.0.0.1:5001/project-name/us-central1/api

It should be used as the following in your app:

http://192.168.1:5001/project-name/us-central1/api

This step is crucial because it tells the iOS app where to find the local emulator on the network.

Updating firebase.json

Update the firebase.json file with your Mac's IP address, just like you did before.

{
  "emulators": {
    "functions": {
      "source": "functions",
      "host": "192.168.1",
      "port": 5001
    }
  }
}

Loading an HTTP URL

On the app side, you may need to add to the Info.plist to load the HTTP url. Add the following to set up an exception in the App Transport Security settings:

  <key>NSAppTransportSecurity</key>
  <dict>
      <key>NSExceptionDomains</key>
      <dict>
          <key>192.168.1.1</key>
          <dict>
              <key>NSExceptionAllowsInsecureHTTPLoads</key>
              <true/>
              <key>NSIncludesSubdomains</key>
              <true/>
          </dict>
      </dict>
  </dict>
Use it only for development and debugging, and consider having different Info.plist configurations for development and production builds.

Run your setup. If you followed the steps correctly, hitting the endpoint should display some activity in your terminal:

i functions: Beginning execution of "us-central1-api"
i functions: Finished "us-central1-api" in 9.71475ms

With this, you know you successfully connected your iOS device to the Firebase Cloud Functions emulator. On-device testing of your Firebase functions!