'Run two function projects at the same time

Can we run two Firebase Function projects with the emulator at the same time? We want to test the interaction of two Firebase Function projects locally.

We have tried running the two projects on different ports.

/project1$ firebase -p 5000 serve --only functions
/project2$ firebase -p 5001 serve --only functions // 500 errors

If we do the above, we receive a 500 error on port 5001, when we start the emulator on that port after starting the emulator on port 5000.

Further, if we try to run the emulator on the same port, we receive a 404 error on the emulator that we started second.

/project1$ firebase -p 5000 serve --only functions
/project2$ firebase -p 5000 serve --only functions // 404 errors

Needless to say the functions work just fine when we do not try to run the simultaneously.



Solution 1:[1]

According to Doug Stevenson's comments to the question, it's entirely possible that the emulator uses more ports than the one it says it is using, and that it is trying to listen on several ports starting at the number it says it is using. So, to use the Firestore Function Emulator on more than one project at a time, it is worth trying to use port numbers that have some distance from each other. E.g.

Probably will work:

/project1$ firebase -p 5000 serve --only functions
/project2$ firebase -p 8000 serve --only functions

Probably will NOT work:

/project1$ firebase -p 5000 serve --only functions
/project2$ firebase -p 5001 serve --only functions // 500 errors

Solution 2:[2]

Basically you need to have two configuration files with different ports for each emulator.

This is how I do it.

I have two Firebase config files inside functions/emulator-tests/config. Each one specifies the ports emulators should listen on (functions, auth and firestore).

Part of my project structure:

functions
  emulator-tests
    config
      firebase.staging.json // for staging emulator
      firebase.prod.json // for prod emulator
  src
  firebase.json // default config I had
  package.json

functions/emulator-tests/config/firebase.prod.json

{
  "functions": {
    "source": "../../"
  },
  "emulators": {
    "auth": {
      "port": 9099
    },
    "functions": {
      "port": 5001
    },
    "firestore": {
      "port": 8080
    },
    "ui": {
      "enabled": true,
      "port": 4000
    }
  }
}

functions/emulator-tests/config/firebase.staging.json

{
  "functions": {
    "source": "../../"
  },
  "emulators": {
    "auth": {
      "port": 9095
    },
    "functions": {
      "port": 5005
    },
    "firestore": {
      "port": 8085
    },
    "ui": {
      "enabled": true,
      "port": 4005
    }
  }
}

As you can see, the difference is just the port every emulator listens on. You can define different ports if you want.

So, to start the staging emulators I run this (from inside the functions folder):

firebase emulators:start --config=emulator-tests/config/firebase.staging.json

And to start the prod emulators I run this from another terminal:

firebase emulators:start --config=emulator-tests/config/firebase.prod.json

You could add those commands as scripts in package.json.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Shaun Luttin
Solution 2 Daniel Muñoz