This library extends the TestContainers project by providing a custom container for running Google Firebase Emulators within a Docker environment. It allows seamless integration of Firebase's local emulators into your test setup.
- Run Firebase emulators in isolated Docker containers.
- Configure individual emulators with custom settings.
- Support for importing/exporting emulator data.
- Easy setup for Firebase Hosting, Firestore, Storage, and more.
The following emulators have been verified to work:
- Firebase Auth
- Firebase Firestore
- Firebase Emulator UI
- Firebase Hosting
- Realtime Database
- PubSub
- Cloud Storage
- Functions
The following emulators are currently unverified:
- EventArc
Add the following dependency to your pom.xml
:
<dependency>
<groupId>nl.group9.testcontainers</groupId>
<artifactId>firebase-emulator-container</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>
FirebaseEmulatorContainer container = FirebaseEmulatorContainer.builder()
.withFirebaseVersion("latest")
.withProjectId("my-test-project")
.withFirebaseConfig()
.withEmulators(
FirebaseEmulatorContainer.Emulator.AUTHENTICATION,
FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE
)
.done()
.build();
container.start();
The FirebaseEmulatorContainer
provides a flexible configuration system for Docker options, Firebase settings, and emulator-specific configurations.
Customize the Docker environment for the emulator container:
.withDockerConfig()
.withImage("node:20-alpine") // Base image for the container
.withUserId(1000) // User ID inside the container
.withGroupId(1000) // Group ID inside the container
.followStdOut(true) // Pipe the stdout of the container to the logging of the host
.followStdErr(true) // Pipe the stderr of the container to the logging of the host
.done()
When running in a non-Docker-Desktop environment, you need to specify the user id and the group id to
allow the docker container to read/write data from the volumes mounted on the host system. Two
convenience methods (withUserIdFromEnv
and withGroupIdFromEnv
) have been created to try to read this info from an environment variable. These methods will silently fail if these IDs cannot be read.
Configure Firebase-specific settings:
- Project ID: Required for the Authentication emulator.
- Firebase Version: Specify the version of
firebase-tools
. - Token: Google Cloud CLI token for authentication.
- Debug: Enable debug logging of firebase
.withFirebaseVersion("latest")
.withCliArguments()
.withProjectId("test-project-id")
.withToken("your-firebase-token")
.withDebug(true)
.done()
Specify a directory to import/export emulator data:
.withCliArguments()
.withEmulatorData(Paths.get("/path/to/emulator/data"))
.withImportExport(ImportExport.IMPORT_ONLY)
.done()
- Java Tool Options:
.withJavaToolOptions("-Xms512m -Xmx1024m")
.done()
Enable and configure specific emulators:
.withFirebaseConfig()
.withEmulators(
FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE,
FirebaseEmulatorContainer.Emulator.REALTIME_DATABASE
)
.withEmulatorOnFixedPort(FirebaseEmulatorContainer.Emulator.PUB_SUB, 8085)
.done()
Note: do mind that the default port for Firestore conflicts with the default ports for many webapplication frameworks (8080).
Configure Firebase Hosting:
.withFirebaseConfig()
.withHostingPath(Paths.get("/path/to/hosting/content"))
.done()
Configure Firebase Functions
.withFirebaseConfig()
.withFunctionsFromPath(Patahs.get("/path/to/functions"))
.withFunctionIgnores(new String[]{"node_modules"})
.done()
Set custom rules for Cloud Storage:
.withFirebaseConfig()
.withStorageRules(Paths.get("/path/to/storage.rules"))
.done()
Set custom rules and indexes for Firestore:
.withFirebaseConfig()
.withFirestoreRules(Paths.get("/path/to/firestore.rules"))
.withFirestoreIndexes(Paths.get("/path/to/firestore.indexes.json"))
.done()
-
Custom
firebase.json
:.readFromFirebaseJson(Paths.get("/path/to/firebase.json"))
When using a custom firebase.json file, please make the following changes to ensure the emulator runs as expected. These changes will ensure the emulator behaves the same as running the emulator from the normal CLI interface:
- Add
"host" : "0.0.0.0"
to all emulator entries - Add the hub, logging and UI emulators to the emulators configuration
{ "emulators" : { "ui": { "port": 4000, "enabled": true, "host": "0.0.0.0" }, "hub": { "port": 4400, "host": "0.0.0.0" }, "logging": { "port": 4500, "host": "0.0.0.0" } } }
- If you use Firestore, also set the Firestore Websocket port
{ "emulators" : { "firestore": { "port": 8080, "websocketPort" : 9150, "host": "0.0.0.0" } } }
- For both entries, you can of course use your own custom ports, where needed.
- Add
Emulator | Default Port | Description |
---|---|---|
Authentication | 9099 | Auth emulator |
Emulator Suite UI | 4000 | Emulator management UI |
Emulator Suite UI Hub | 4400 | Emulator management UI Hub endpoint |
Emulator Suite UI Logging | 4500 | Emulator management UI Logging |
Realtime Database | 9000 | Database emulator |
Firestore | 8080 | Firestore emulator |
Firestore WebSocket | 9150 | Firestore WS emulator |
Cloud Storage | 9199 | Storage emulator |
Firebase Hosting | 5000 | Hosting emulator |
Firebase Functions | 5001 | Functions emulator |
Pub/Sub | 8085 | Pub/Sub emulator |
We welcome contributions! Here's how you can get started:
- Fork the repository.
- Create a new branch for your feature or bugfix.
- Write tests for your changes.
- Open a pull request with a clear description of the changes.
For major changes, please open an issue first to discuss what you would like to change.
This project is licensed under the Apache License. See the LICENSE file for details.