Emulator
The emulator allows you to make changes to local, temporary data. By default it is a blank slate every time you start up an emulator.
Setup
I had a little trouble with the setup, but eventually figured it out. You need to have Java installed to run the emulator. For my Mac m2 I needed to install the Arm 64 DMG Installer.
WARNING
If you run into the error Error: It looks like you haven't used Cloud Firestore in this project before
follow the instructions at this Stack Overflow thread.
Connect to the Emulator
// switch this to true to use the production data.
let production = false;
const firebaseConfig = {
apiKey: ...,
authDomain: ...,
projectId: ...,
storageBucket: ...,
messagingSenderId: ...,
appId: ...,
};
const app = firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();
const auth = firebase.auth();
console.log(firebase.auth);
if (!production) {
db.useEmulator("localhost", 8080);
auth.useEmulator("http://localhost:9099");
}
I learned that using the auth pre-built UI doesn't connect to the emulator. But I don't think I would use that in a real site anyway.
Start the Emulator with Data
You can start the emulator with the previous data you had by running a specific command. This is not from the cloud, but whatever you are locally testing.
firebase emulators:start --import=test-data --export-on-exit
It doesn't look like the test-data
directory needs to exist to import. It will be the name of the directory for the exported data.
Copy production data to emulator
This script is heavily based off of this article.
It's a pain to start from scratch with given data. This is a way to get a copy of live data to the emulator that you can freely manipulate and it won't affect production.
This script uses sandbox-ca45d as the project ID (found in the app settings or firebase projects:list
), and uses test-data for the directory where the data goes.
Name this file refreshdb.sh
, put it in the root of the project, and run bash refreshdb.sh
.
set -e
# This was taken from this article:
# https://medium.com/firebase-developers/how-to-import-production-data-from-cloud-firestore-to-the-local-emulator-e82ae1c6ed8
# 1. Make sure Python 3 and gsutil are installed
# python3 -V
# gsutil version
# 2. Make sure that billing is enabled (and set a limit of $2)
# Note that this is just for alerts. It doesn't shut down the project if it goes over.
# Firebase Console -> Spark Plan change to Blaze
# 3. Initial Setup. You should only need to do this once
# firebase login
# firebase projects:list
# firebase use sandbox-ca45d
# gcloud projects list
# gcloud config set project sandbox-ca45d
# 4. Optional, manual way to copy data
# # 4.a Remove old data
# rm -rf ./test-data
# gsutil -m rm -rf gs://sandbox-ca45d.appspot.com/test-data
# # 4.b Add new data
# gcloud firestore export gs://sandbox-ca45d.appspot.com/test-data
# gsutil -m cp -r gs://sandbox-ca45d.appspot.com/test-data .
# 5. Use this instead of 4
#Remove previous bucket if exists
delete_previous_version_if_exists() {
#We either delete local folder and bucket object or just a bucket
rm -rf ./test-data &&
gsutil -m rm -rf gs://sandbox-ca45d.appspot.com/test-data ||
gsutil -m rm -rf gs://sandbox-ca45d.appspot.com/test-data
}
export_production_firebase_to_emulator() {
#Export production firebase to emulator bucket
gcloud firestore export gs://sandbox-ca45d.appspot.com/test-data
#Copy to local folder
gsutil -m cp -r gs://sandbox-ca45d.appspot.com/test-data .
}
#Run bash functions, either delete previous bucket and local folder if exists for update or just export clean way
delete_previous_version_if_exists && export_production_firebase_to_emulator ||
export_production_firebase_to_emulator
firebase emulators:start --import=test-data --export-on-exit
For any subsequent sessions you can just run firebase emulators:start --import=test-data --export-on-exit
which will preserve your data from production with whatever modifications you made. If you need to start with a mirror copy of production, you will need to run bash refreshdb.sh
again.
WARNING
Every time you refresh data all of the authentication set up will disapear. ALSO I still need to test this script with cloud storage and functions and such. I have only tested this with Firestore.