Firebase Emulator setup for Flutter

Aug 13, 2021 . 5 min Muhammed Mukhthar CM Cover Image

Maybe you’re trying to set up a local dev environment for your Firebase Project. Or you may want to try out Firebase Functions, but are on the spark plan of Firebase.

Whatever It may be, Firebase offers us an emulator suite we can use to experiment with Firebase locally.

Install Firebase CLI

First of all, we need to Install the Official Firebase CLI on our Computer.

npm install firebase-tools -g

Run the above command to Install the Firebase CLI globally to our System.

Next, we have to log in to the Firebase CLI using firebase login. This will take you to the browser for confirming login. Click allow to login to the cli. And It will show a Successful Message.

CLI login Succesful!

CLI login succesful!

Initializing Firebase Project

The next step is to initialize your firebase project. Go to your Flutter project which you want to use Firebase, and run the below command.

firebase init

It will show Firebase in a large yellow font. The prompt will ask you some questions, the first being are you ready to proceed. Press Y to continue.

Selecting Services

The next prompt will be to select the Services we want to initialize. Select all the services you need by pressing the spacebar to select. Then click enter to continue.

? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices.
 ( ) Hosting: Set up GitHub Action deploys
 ( ) Storage: Configure a security rules file for Cloud Storage
 ( ) Emulators: Set up local emulators for Firebase products
>( ) Remote Config: Configure a template file for Remote Config
 ( ) Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance
 ( ) Firestore: Configure security rules and indexes files for Firestore
 ( ) Functions: Configure a Cloud Functions directory and its files
(Move up and down to reveal more choices)

Don’t forget to select Emulators Here!

Selecting Project

The next step is to select which project we want our Flutter project to associate with. For the sake of this tutorial, I have already created a Firebase Project in my Firebase Console. If you haven’t yet, you can follow My post on setting up Firebase for Android on Flutter.

So select Use an existing project in this prompt

? Please select an option: (Use arrow keys)
> Use an existing project
  Create a new project
  Add Firebase to an existing Google Cloud Platform project
  Don't set up a default project

It will show a list of all the projects you’ve created and you’ll have to select one.

OR

you can just select Don’t set up a default project and move on!.

The next couple of prompts will be based on the services you’ve selected in the previous step.

For this post, we’ll be covering only the Emulator Setup. The CLI will ask which emulators we want to set up.

? Which Firebase emulators do you want to set up? Press Space to select emulators, then Enter to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection)
>( ) Authentication Emulator
 (*) Functions Emulator
 ( ) Firestore Emulator
 ( ) Database Emulator
 ( ) Hosting Emulator
 ( ) Pub/Sub Emulator
 ( ) Storage Emulator

Select all the emulators you want to use in this project.

Then it will ask which port should be used for each emulator. Click enter to select the default options.

When the CLI asks whether to download the emulators now or later, click Y to download them now.

After these, the CLI will show a success message.

+  Firebase initialization complete!

To the Flutter-Side

Next, we are going to set up our Flutter project use the local emulators instead of our Production Firebase Project.

Each of the Firebase plugins for Flutter has something like .useEmulator in them. So for convenience, I have created a function to make all of the Firebase products use Emulators.

Future _connectToFirebaseEmulator() async {
  final localHostString = '{your system Ip Address}';

  FirebaseFirestore.instance.settings = Settings(
    host: '$localHostString:8080',
    sslEnabled: false,
    persistenceEnabled: false,
  );

  await FirebaseStorage.instance
      .useStorageEmulator('http://$localHostString', 9199);

  await FirebaseAuth.instance.useAuthEmulator('http://$localHostString', 9099);
}

The official documentation recommends just use localhost instead of your system Ip Address, But I will explain it in a bit.

When I was trying to connect to emulators from a Real Device (aka not an android emulator), I was unable to connect to them using only localhost. If you’re using Android or iOS emulators, you may stick with the localhost version.

Future _connectToFirebaseEmulator() async {

  FirebaseFirestore.instance.settings = Settings(
    host: 'localhost:8080',
    sslEnabled: false,
    persistenceEnabled: false,
  );

  await FirebaseStorage.instance
      .useStorageEmulator('localhost', 9199);

  await FirebaseAuth.instance.useAuthEmulator('localhost', 9099);
}

we have to call the above function to be the runApp method in main.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await _connectToFirebaseEmulator();
  runApp(
    MyApp(),
  );
}

Don’t leave just yet! For my hacked out version to work, we have to make changes to one more file.

Adjusting firebase.json file

There is a file named firebase.json at the root of our Flutter project. Don’t worry, it was created during our Firebase CLI initialization.

By default, it will look something like this.

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "functions": {
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint",
      "npm --prefix \"$RESOURCE_DIR\" run build"
    ]
  },
  "emulators": {
    "auth": {
      "port": 9099
    },
    "functions": {
      "port": 5001
    },
    "firestore": {
      "port": 8080
    },
    "pubsub": {
      "port": 8085
    },
    "storage": {
      "port": 9199
    },
    "ui": {
      "enabled": true
    }
  }
}

There is a port key in every emulator listed in the JSON. We need to add a host key to them.

We have to provide our system IP as the host. To get our IP address, we can run ipconfig on windows and ifconfig on Linux. In my case, It was 192.168.42.54

So my firebase.json looks like this.

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "functions": {
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint",
      "npm --prefix \"$RESOURCE_DIR\" run build"
    ]
  },
  "storage": {
    "rules": "storage.rules"
  },
  "emulators": {
    "auth": {
      "host": "192.168.42.54",
      "port": 9099
    },
    "functions": {
      "host": "192.168.42.54",
      "port": 5001
    },
    "firestore": {
      "host": "192.168.42.54",
      "port": 8080
    },
    "storage": {
      "host": "192.168.42.54",
      "port": 9199
    },
    "ui": {
      "host": "192.168.42.54",
      "enabled": true
    }
  }
}

Running the emulators

Now is the time to run’em! 🎉

run the below code in the terminal on the root of your Flutter Project.

firebase emulators:start

wait some time and you’ll see the magic.

Description

Firebase emulators running

Wrap

You can find more articles related to Firebase Here

Hope you found something useful here.

I’m always open to suggestions!

Let me know your suggestions and opinions on Twitter DM or drop a mail a [email protected].

If you’re feeling too generous, you can support me through Buy Me a Coffee.

Finally, if you found this helpful, please share this within your reach so that more people can benefit from this. And Follow me on Twitter for getting more posts like these 😉.