Before you jump in with Firebase Local Emulator Suite, make sure you've created
a Firebase project, set up your development environment, and selected and
installed Firebase SDKs for your platform according to the
Get started with
Firebase
topics for your platform:
Apple
,
Android
or
Web
.
Prototype and test
The Local Emulator Suite contains several product emulators, as described in
Introduction to Firebase Local Emulator Suite
.
You can prototype and test with individual emulators as well as combinations of
emulators, as you see fit, corresponding to which Firebase products you're using
in production.
For this topic, to introduce the Local Emulator Suite workflow, let's assume
you're working on an app that uses a typical combination of products: a Firebase
database and cloud functions triggered by operations on that database.
After you locally initialize your Firebase project, the development cycle using
Local Emulator Suite will typically have three steps:
Prototype features interactively with the emulators and Emulator Suite UI.
If you're using a database emulator or the Cloud Functions emulator,
perform a one-time step to connect your app to the emulators.
Automate your tests with the emulators and custom scripts.
Locally initialize a Firebase project
Make sure that you
install the CLI
or
update to its latest version
.
curl -sL firebase.tools | bash
If you haven't already done so, initialize the current working directory as a
Firebase project, following the onscreen prompts to specify you're using
Cloud Functions
and either
Cloud Firestore
or
Realtime Database
:
firebase init
Your project directory will now contain Firebase configuration files, a
Firebase Security Rules definition file for the database, a
functions
directory
containing cloud functions code, and other supporting files.
Prototype interactively
Local Emulator Suite is designed to let you quickly prototype new features,
and the Suite's built-in user interface is one of its most useful prototyping
tools. It's a bit like having the Firebase console running locally.
Using Emulator Suite UI, you can iterate the design of a database, try out
different dataflows involving cloud functions, evaluate Security Rules changes,
check logs to confirm how your back-end services are performing, and more. Then,
if you want to start over, just clear your database and start fresh
with a new design idea.
It's all available when you start the Local Emulator Suite with:
firebase emulators:start
To prototype our hypothetical app, let's set up and test a basic cloud function
to modify text entries in a database, and both create and populate that database
in the Emulator Suite UI to trigger it.
- Create a cloud function triggered by database writes by editing the
functions/index.js
file in your project directory. Replace the
contents of the existing file with the following snippet. This function
listens for changes to documents in the
messages
collection,
converts the contents of a document's
original
field to
uppercase, and stores the result in that document's
uppercase
field.
const functions = require('firebase-functions');
exports.makeUppercase = functions.firestore.document('/messages/{documentId}')
.onCreate((snap, context) => {
const original = snap.data().original;
console.log('Uppercasing', context.params.documentId, original);
const uppercase = original.toUpperCase();
return snap.ref.set({uppercase}, {merge: true});
});
- Launch the Local Emulator Suite with
firebase emulators:start
. The Cloud Functions and database
emulators start up, automatically configured to interoperate.
- View the UI in your browser at
http://localhost:4000
.
Port 4000 is the default for the UI, but check terminal messages output by
the Firebase CLI. Note the status of available emulators. In our case,
the Cloud Functions and Cloud Firestore emulators will be running.
- In the UI, on the
Firestore > Data
tab, click
Start collection
and follow the prompts to create a new document in a
messages
collection, with fieldname
original
and value
test
. This triggers our cloud function. Observe that a new
uppercase
field appears shortly, populated with the string
"TEST".
- On the
Firestore > Requests
tab, examine requests made to your
emulated database, including all Firebase Security Rules evaluations performed
as part of fulfilling those requests.
- Check the
Logs
tab to confirm your function did not run into errors
as it updated the database.
You can easily iterate between your cloud function code and interactive
database edits until you get the data flow you're looking for, without touching
in-app database access code, recompiling and re-running test suites.
Connect your app to the emulators
When you've made good progress with interactive prototyping and have settled on
a design, you'll be ready to add database access code to your app using the
appropriate SDK. You'll keep using the database tab and, for functions, the
Logs
tab in Emulator Suite UI to confirm that your app's behavior
is correct.
Remember that the Local Emulator Suite is a local development tool. Writes
to your production databases will not trigger functions you are prototyping
locally.
To switch over to having your app make writes to the database, you'll need
to point your test classes or in-app configuration at the Cloud Firestore
emulator.
Kotlin+KTX
// 10.0.2.2 is the special IP address to connect to the 'localhost' of
// the host computer from an Android emulator.
val firestore = Firebase.firestore
firestore.useEmulator("10.0.2.2", 8080)
firestore.firestoreSettings = firestoreSettings {
isPersistenceEnabled = false
}
Java
// 10.0.2.2 is the special IP address to connect to the 'localhost' of
// the host computer from an Android emulator.
FirebaseFirestore firestore = FirebaseFirestore.getInstance();
firestore.useEmulator("10.0.2.2", 8080);
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
.setPersistenceEnabled(false)
.build();
firestore.setFirestoreSettings(settings);
Swift
let settings = Firestore.firestore().settings
settings.host = "127.0.0.1:8080"
settings.cacheSettings = MemoryCacheSettings()
settings.isSSLEnabled = false
Firestore.firestore().settings = settings
Web modular API
import { getFirestore, connectFirestoreEmulator } from "firebase/firestore";
// firebaseApps previously initialized using initializeApp()
const db = getFirestore();
connectFirestoreEmulator(db, '127.0.0.1', 8080);
Web namespaced API
// Firebase previously initialized using firebase.initializeApp().
var db = firebase.firestore();
if (location.hostname === "localhost") {
db.useEmulator("127.0.0.1", 8080);
}
Automate your tests with custom scripts
Now for the last overall workflow step. Once you've prototyped your feature
in-app and it looks promising on all your platforms, you can turn to final
implementation and testing. For unit testing and CI workflows, you can start up
emulators, run scripted tests, and shut down emulators in a single call with
the
exec
command:
firebase emulators:exec "./testdir/test.sh"
Explore individual emulators in more depth
Now that you've seen what the basic client-side workflow looks like, you can
continue with details about the individual emulators in the Suite, including how
to use them for server-side app development:
What next?
Be sure to read the topics related to specific emulators linked above. Then: