Seeding mock data to the Firebase Local Emulator Suite
Tags: firstpost, firebase, firestore, faker
Published: 2021-01-25 19:28:41

I have recently been working on a React/Firebase side project to level up my skills and provide a playground to experiment with different techniques, patterns and libraries. One of my favorite features in Firebase is the [Local Emulator Suite](https://firebase.google.com/docs/emulator-suite).

> The Firebase Local Emulator Suite is a set of advanced tools for developers looking to build and test apps locally using Cloud Firestore, Realtime Database, Authentication, Cloud Functions, Pub/Sub, and Firebase Hosting. It provides a rich user interface to help you get running and prototyping quickly.

The Local Emulator Suite is fairly easy to set up but be sure to reference the [docs](https://firebase.google.com/docs/emulator-suite) for full details.

Regarding the actual code in your project, you first need to make sure the emulator ports are defined in your `firebase.json` file like so ...

```
firebase.json
```

```json
"emulators": {
  "auth": {
    "port": 9099
  },
  "firestore": {
    "port": 8080
  },
  "ui": {
    "enabled": true,
    "port": 4000
  }
}
```

Then in your app's `firebase.js` file, include an if statement that checks your Node environment. If you are in 'development' mode your app will automatically run against the emulators and will use the ports that you defined in your `firebase.json` file.

```
firebase.js
```
```javascript
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';

export const firebaseConfig = {
  apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.REACT_APP_FIREBASE_DATABASE_URL,
  projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_FIREBASE_APP_ID,
  measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID
};

if (!firebase.apps.length) {
  firebase.initializeApp(firebaseConfig);
}

const app = firebase.app();
const auth = firebase.auth();
const db = firebase.firestore();

if (process.env.NODE_ENV === 'development') {
  console.log('testing locally -- hitting local auth and firestore emulators');
  auth.useEmulator('http://localhost:9099/');
  db.useEmulator('localhost', 8080);
}

console.log(app.name ? 'Firebase Mode Activated!' : 'Firebase not working :(');
```

Now navigate to the root of your project in your terminal and start the emulators by running `firebase emulators:start`. You should see this in your terminal

![image](https://dev-to-uploads.s3.amazonaws.com/i/tz1b7810a00td58vkzh8.png)
 
and the Emulator UI at [http://localhost:4000](http://localhost:4000)

![emulator-console](https://dev-to-uploads.s3.amazonaws.com/i/j1auiku0ahzz86qfa8oq.jpg) 
 
Now that you have emulators set up and running, it is time to seed the data to Firestore to develop against.

## Seeding Data to Firestore Local Emulator

When developing locally it is helpful to have a data set to work with. While there are a few approaches to seeding data, including [this approach via the Firebase docs](https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data), I chose to go with a simple script.

Create a script in your project root called `dbseed.js`.

```
dbseed.js
```
```javascript
const admin = require('firebase-admin'); // required
const faker = require('faker'); // amazing library!

// initialization
const projectId = 'your-firebase-project-id';
process.env.FIRESTORE_EMULATOR_HOST = 'localhost:8080';
admin.initializeApp({ projectId });

const db = admin.firestore();

// seed function
function getSeedData() {
  try {
    [...Array(10).keys()].map(() =>
      db.collection('events').add({
        author_name: faker.name.firstName() + '' + faker.name.lastName(),
        author_profile_pic: faker.image.imageUrl(),
        title: faker.commerce.productName(),
        description: faker.commerce.productDescription(),
        address: {
          addr_1: faker.address.streetAddress(),
          addr_2: faker.address.secondaryAddress(),
          city: faker.address.city(),
          state: faker.address.state(),
          zipCode: faker.address.zipCode()
        }
      })
    );
    console.log('database seed was successful');
  } catch (error) {
    console.log(error, 'database seed failed');
  }
}

getSeedData();

```
This script contains the required imports and initialization and runs a function that writes an array of objects to an 'events' collection.

Once the emulator suite is running, navigate to [Firestore Emulator UI](http://localhost:4000/firestore) then run `node dbseed.js` in a separate terminal window/tab.

You will see that the empty Firestore db is seeded with an array of Faker objects. Faker.js is an amazing library. Be sure to check out all the options at the [https://github.com/marak/Faker.js/](Github repo)

![Seed mock data to the Firebase Local Emulator Suite](https://media.giphy.com/media/xfZSmWuWZi1tdJaLPA/giphy.gif)

Success! Now you can develop against test data while work within the Firebase Local Emulator Suite.

## What about working with real production data?
You can also work with your production data if that is a better fit. Set up is more involved but still a nice approach. Check out the [Firestore Docs](https://firebase.google.com/docs/emulator-suite/install_and_configure) to learn how to export your production data then import it when starting the emulators.

## Conclusion

Working with mock data is an essential part of development and is something that I struggled with when working in the Firebase Local Emulator Suite. This simple approach allows me to seed the database quickly. Thanks for reading and I hope this helps your workflow. Happy coding!