Setting up the Firebase emulator: should you use getFirestore() or getFirestore(firebaseApp)?

After delving into the process of connecting your app to the Firebase emulators like Firestore emulator, I came across the primary documentation which outlined the steps for Web version 9:

import { getFirestore, connectFirestoreEmulator } from "firebase/firestore";

// firebaseApps previously initialized using initializeApp()
const db = getFirestore(); // <-- Notably, no passing of firebaseApp here
connectFirestoreEmulator(db, 'localhost', 8080); 

I've also come across an alternative way to call getFirestore():

import { initializeApp } from 'firebase/app';
import { getFirestore, connectFirestoreEmulator } from 'firebase/firestore';

const config = { /* Firebase project config here  */ };
const firebaseApp = initializeApp(config);
const db = getFirestore(firebaseApp); // <-- Note that firebaseApp is passed-in
connectFirestoreEmulator(db, 'localhost', 8080);

In the Firestore API docs for getFirestore(), it mentions that:

"Returns the existing Firestore instance that is associated with the provided FirebaseApp. If no instance exists, initializes a new instance with default settings."

This has left me puzzled about whether I should pass in my initialized firebaseApp when calling

getFirestore()</code based on that description. Since I have multiple Firebase services to emulate and have them communicate with each other, I believe I <em>should</em> provide my <code>firebaseApp
.

Which approach is correct? Are there any potential pitfalls I should be aware of?

Answer №1

After digging into the source code, I discovered the inner workings of the situation:

The getFirestore method's code looks like this:

/**
 * Retrieves the existing {@link Firestore} instance associated with the
 * provided {@link @firebase/app#FirebaseApp}. If there is no instance, a new one
 * is initialized with default settings.
 *
 * @param app - The {@link @firebase/app#FirebaseApp} instance that the returned {@link Firestore}
 * instance belongs to.
 * @returns The {@link Firestore} instance for the given app.
 */
function getFirestore(app$1 = app.getApp()) {
    return app._getProvider(app$1, 'firestore').getImmediate();
}

If you do not provide an app instance to the function, it assigns the app variable to app.getApp().

Earlier in the code, app is defined as

require("@firebase/app")
, so we must examine the getApp method in that package.

The declaration of the getApp method is as follows:

/**
 * Retrieves a {@link @firebase/app#FirebaseApp} instance.
 *
 * When called without arguments, the default app is returned. Providing an app name
 * will return the app associated with that name.
 *
 * An exception will be thrown if the retrieved app has not been
 * initialized yet.
 *
 * @param name - Optional name of the app to return. If none is provided,
 *   the default will be `"[DEFAULT]"`.
 *
 * @returns The app corresponding to the given name.
 *   If no name is provided, the default app will be returned.
 *
 * @public
 */
export declare function getApp(name?: string): FirebaseApp;

This indicates that when a firebase app is initialized, it is assigned a unique identifier name.

The declaration of the initializeApp method is below:

/**
 * Creates and initializes a {@link @firebase/app#FirebaseApp} instance.
 *
 * See
 * {@link
 *   https://firebase.google.com/docs/web/setup#add_firebase_to_your_app
 *   | Add Firebase to your app} and
 * {@link
 *   https://firebase.google.com/docs/web/setup#multiple-projects
 *   | Initialize multiple projects} for detailed documentation.
 *
 * @param options - Options to configure the app's services.
 * @param name - Optional name of the app to initialize. If no name
 *   is provided, the default is `"[DEFAULT]"`.
 *
 * @returns The initialized app.
 *
 * @public
 */
export declare function initializeApp(options: FirebaseOptions, name?: string): FirebaseApp;

This means that if you call initializeApp without specifying a name for the instance, it will be created with the default name "[DEFAULT]"

In conclusion, unless you explicitly name your firebase app instance, you do not need to pass it when calling getFirestore. It can retrieve your primary app instance automatically from the firebase/app package when needed.

There should be no difference between manually passing the app instance to getFirestore or letting Firestore obtain the instance directly through the firebase/app package.

Answer №2

If you are working with a single Firebase app, you have the flexibility to choose either method. However, if you are dealing with multiple apps, it is necessary to initialize each app separately by providing their configurations and accessing their specific firestore.

import { getFirestore, connectFirestoreEmulator } from "firebase/firestore";

const db = getFirestore();
connectFirestoreEmulator(db, 'localhost', 8080); 

This approach is suitable when there is already an initialized firebase app in your context, and only one app needs to be accessed.

For scenarios where multiple firebase apps are required, individual initialization and specification of the target firestore are necessary:

Here's how it can be done:

import { initializeApp } from 'firebase/app';
import { getFirestore, connectFirestoreEmulator } from 'firebase/firestore';

const config = { /* Add Firebase project configuration here */ };
const firebaseApp = initializeApp(config);
const db = getFirestore(firebaseApp);
connectFirestoreEmulator(db, 'localhost', 8080);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can the Header of a get-request for an npm module be modified?

Currently, I am utilizing an npm module to perform an API request: const api_req = require('my-npm-module-that-makes-an-api-request'); However, I am seeking a way to modify the user-agent used for requests generated internally by the npm module ...

The challenge of handling Set type in TypeScript errors

I'm currently facing two errors while trying to convert a function to TypeScript. The issue lies with the parameters, which are of type Set import type {Set} from 'typescript' function union<T>(setA: Set<T>, setB: Set<T>) ...

issues encountered with sending a multidimensional array using ajax, specifically with the index[0]

I'm struggling with sending a multidimensional array from PHP to Javascript/jQuery, encountering a peculiar issue. Upon transmitting index 0 through json_encode($array);, the desired response format is successfully received by the client: [[0,0],[1, ...

Can studying Titanium Appcelerator enhance my comprehension of NodeJS?

As I dive into the world of building mobile JavaScript Applications in Titanium Appcelerator, I've come across documentation that mentions the use of the V8 Engine as their JS interpreter for Android. Additionally, some of the approaches seem to be in ...

Securing the connection between clients and servers through encryption

For my mobile client, I am using Xamarin, with node.js as my backend and MongoDB as the database. The main issue I am facing is how to securely store user data in the database. If I only do server-side encryption, there is a risk of hackers intercepting th ...

Obtain one option from the two types included in a TypeScript union type

I am working with a union type that consists of two interfaces, IUserInfosLogin and IUserInfosRegister. The TUserInfos type is defined as the union of these two interfaces. export interface IUserInfosLogin { usernameOrEmail: string; password: string; } ...

The basic shapes in the scene are just out of sight

Sorry for the easy question, but I'm having trouble getting the BoxGeometry to show up in the scene. The red background is displaying correctly. var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(0, window.innerWidth / window.inn ...

Encountered an issue loading a resource due to a lost network connection while using Safari 9 and JBoss WildFly 8.2

After successfully deploying my War file to the JBoss Wildfly 8.2 server, I attempted to access the application link from a remote MAC machine. The application opened correctly, but some functionalities were not working properly. An error message popped u ...

How can I automatically choose the first element in an ng-repeat loop using AngularJS?

Do you have any thoughts on how to accomplish this task? Currently, I have set up one controller where if you click on an element, an animation appears above. However, my goal is to have the first element automatically active/clicked as soon as the page l ...

Error messages are appearing during the installation of mediasoup

Attempting to install via Command Prompt on Windows 7 64-bit https://i.sstatic.net/MBLNR.png following the command npm cache --force cleanhttps://i.sstatic.net/dLvHP.png ...

"Is it possible to differentiate between a variable that is BehaviorSubject and one that is not

I am dealing with a variable that can be of type Date or BehaviorSubject<Date | null>. My concern is figuring out how to determine whether the variable is a BehaviorSubject or not. Can you help me with this? ...

Utilize Office Scripts to update values across numerous worksheets

Looking for ways to improve the performance of this script, as it currently takes 45 seconds to run. Any ideas? function main(workbook: ExcelScript.Workbook) { try { const sheets = workbook.getWorksheets(); for (let sheet of sheets) { const break ...

Transmitting information from JavaScript to a PHP script

I am currently using a function that grabs text from a PHP file on our server and inserts it into an HTML page. However, I now need to modify this function in order to SEND data (specifically a couple of JavaScript variables) to the PHP file instead of si ...

Having trouble getting data to send to node.js server using $.ajax post

Trying to convert a table date into an array and send it to the server side using Ajax post for the first time. Despite following all the suggestions in previous posts, I am still struggling. Utilizing body-parser to extract data on the server side. Any he ...

What is the best way to implement a series of delayed animations in jQuery that are connected

Imagine you have the following items: <div id="d1"><span>This is div1</span></div> <div id="d2"><span>This is div2</span></div> <div id="d3"><span>This is div3</sp ...

Building a follow/unfollow system in Node.jsLet's create a

I am relatively new to programming and I'm looking to implement a follow/unfollow feature in my application. router.put('/user/:id/follow', auth.verifyuser, (req, res)=>{ user.findById(req.params.id) .then((otherUser)=>{ if(otherU ...

Internet Explorer freezing when running selenium executeScript

Hey everyone, I've spent the past couple of days scouring the internet trying to find a solution to my modal dialog problem. There's a wealth of helpful information out there and everything works perfectly fine except for Internet Explorer. Speci ...

Elevation in design ui component

I am having an issue with the height of a theme-ui component I embedded. Even though the console shows it correctly, it is displaying at 100% height. <Embed src={url} sx={{width: '800px', height: '400px'}}/> This embed is contain ...

Switch out the arrow icon in the dropdown menu with an SVG graphic

Looking for a way to customize the dropdown caret in a semantic-ui-react component? Here's how it currently appears: https://i.sstatic.net/GpvfC.png <Dropdown className="hello-dropdown" placeholder="Comapany" onChange={th ...

Need to capture click events on an HTML element? Here's how!

I am attempting to capture click events on an <object/> element that is embedding a Flash file This is the approach I have taken so far: <div class="myban" data-go="http://google.com"> <object class="myban" data="index.swf>">< ...