Journey to the Firebase: Seeding Cloud Firestore and Authentication

Karen Choi
5 min readJul 22, 2021

--

As part of my capstone project at the coding bootcamp, my team decided to use Firebase to serve as our back-end. Building a social media mobile application, we needed a good way to seed our Cloud Firestore with mock user data and create users on Firebase Authentication with mock login credentials simultaneously. While it was possible to manually create a user document in Cloud Firestore and input data to the document, we had multiple fields associated with each user data. If we wanted to seed 100+ users, it would take us a long time. Also, why not automate the process? After all, we are all software engineers!

Let’s begin by reviewing what Firebase and Cloud Firestore are.

No, not this kind of fire.

Firebase is a Backend-as-a-Service (BaaS) platform used to create mobile and web applications. The service is developed and owned by Google. It also manages your application’s servers, API, and database. Cloud Firestore is one of the features offered by Firebase — it is a flexible, scalable NoSQL cloud database that stores data in documents and collections. In this article, we will be using Cloud Firestore to seed our user data.

Before we dive into the seeding script, make sure to prepare your seed data file first. For reference, this is how some of our user data looked like:

Now for the seeding script, require your Firebase configuration file that includes your Firebase setting, such as the API key, Auth domain, and Database URL.

Thankfully, Firebase provides numerous methods you can use to make development easier, with one of the methods being .createUserWithEmailAndPassword(). This method takes in email and password as parameter (if you didn’t already guess from the name) and creates a new user account associated with the specified email and password. As this method is part of the Firebase Authentication service, we need to chain the method to firebase.auth() for proper usage. The method returns a Promise that contains user credentials such as the user’s unique id (uid), email, metadata, and many others. Among these, what we really need is the uid so that we can create the user document with that same uid as the document reference. When the Promise successfully resolves, we can use the response to create the user document with the generated uid and populate the document with each of our seed user data using the FireStore’s .set() method.

When testing our code, we encountered our first error! This is expected in programming. No sweat.

Seriously, no big deal…

Firebase was able to bulk create the users in Authentication, yet only one of the seed users was added to Firestore as a user document. After consulting Google, Stack Overflow, and Firebase documentation, we learned this is indeed the expected behavior of Firebase. If the user is created using the .createUserWithEmailAndPassword() method with Authentication, the newly created user becomes the current user of the application. This means that “there is a user change detected by Firebase, which leads to Firebase closing all outstanding streams and cancels any further requests!”

This led me thinking: if we are bulk creating the users and automatically signing them in, there must be a way to automatically sign them out, right? Without a doubt, we found a Firebase method that signs out the current user: .signOut(). Now we can continue the cycle of creating a new user, signing them in, create a user document in Firestore, and signing them out.

Of course, using the .signOut method alone did not resolve the issue. We faced another roadblock: executing asynchronous code inside loops in a sequential manner was tricky. In fact, JavaScript for loops (including the .forEach and .map methods) do not wait until the asynchronous code finishes executing before moving onto the next iteration of the loop.

Wait for me…

After trying to seed the database using a regular for loop, .forEach, and .map methods and encountering the same error numerous times, I decided to look elsewhere. After all, our team wanted to execute a set of asynchronous functions in a sequential order. Hmm… how can we possibly repeat code sequentially? Wait, did someone say setInterval()?

It turns out that JavaScript’s native setInterval() function is perfect for our purpose. In essence, the setInterval() method executes a provided function code snippet with the given time delay between each function call.

The delay time of 2000 ms (2 seconds) is arbitrary — I made an educated guess that the entire sequence of efficient Firebase calls would take less than 2 seconds. We gave it a shot, and…

Voila! Using setInterval() worked perfectly for our seeding purpose, executing multiple Firebase operations of adding user to the Authentication, creating a user document in our users collection, signing out the user — all in the correct sequential order.

Seeding success!

Below is the complete, final code with comments to facilitate your understanding:

Using the .signOut and setInterval() methods was one way to seed the Cloud Firestore, and I’m sure there are different ways to achieve the same goal. Please feel free to share your approach in the comments below — I would love to hear it. Thank you for reading and happy seeding! 🌱

--

--

Karen Choi

Fullstack Software Engineer. Grace Hopper Grad. Enjoys playing tennis, eating good food, and drinking coffee ❤️