Firebase 模拟器设置:getFirestore() 还是 getFirestore(firebaseApp)?

发布于 2025-01-11 15:32:36 字数 1451 浏览 0 评论 0原文

在研究如何将您的应用连接到 Firebase 模拟器(例如 Firestore 模拟器)时,我发现了主要的 文档说明我们会这样做(Web 版本 9):

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

// firebaseApps previously initialized using initializeApp()
const db = getFirestore(); // <-- Notice they don't pass-in firebaseApp here
connectFirestoreEmulator(db, 'localhost', 8080); 

我还看到了 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); // <-- Notice firebaseApp passed-in
connectFirestoreEmulator(db, 'localhost', 8080);

getFirestore() 的 Firestore API 文档指出:

“返回与关联的现有 Firestore 实例 提供FirebaseApp。如果不存在实例,则初始化一个新的 具有默认设置的实例。”

我对根据该描述调用 getFirestore() 时是否传递初始化的 firebaseApp 感到困惑。我有多个 Firebase 服务我想模仿(并互相交谈),所以我认为我应该传入我的 firebaseApp

哪个是正确的?知道?

When researching how to connect your app to the Firebase emulators (e.g., the Firestore emulator), I found the main documentation stating that we'd do it like this (Web version 9):

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

// firebaseApps previously initialized using initializeApp()
const db = getFirestore(); // <-- Notice they don't pass-in firebaseApp here
connectFirestoreEmulator(db, 'localhost', 8080); 

I've also seen the getFirestore() call done like this:

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); // <-- Notice firebaseApp passed-in
connectFirestoreEmulator(db, 'localhost', 8080);

The Firestore API docs for getFirestore() states that it:

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

I'm confused about whether or not to pass-in my initialized firebaseApp when calling getFirestore() based on that description. I have multiple Firebase services that I want to emulate (and have talk to each other) so I would think that I should pass-in my firebaseApp.

Which is correct? Are there "gotchas" to be aware of?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清浅ˋ旧时光 2025-01-18 15:32:36

我仔细查看了源代码,以了解究竟发生了什么,这就是我发现的内容:

getFirestore 方法的代码如下:

/**
 * Returns the existing {@link Firestore} instance that is associated with the
 * provided {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new
 * instance with default settings.
 *
 * @param app - The {@link @firebase/app#FirebaseApp} instance that the returned {@link Firestore}
 * instance is associated with.
 * @returns The {@link Firestore} instance of the provided app.
 */
function getFirestore(app$1 = app.getApp()) {
    return app._getProvider(app$1, 'firestore').getImmediate();
}

如果您不将应用程序实例传递给该函数,那么它将 app 变量设置为 app.getApp()

在代码的前面,app 被定义为 require("@firebase/app"),因此我们需要查看 getApp 方法那个包裹。

getApp 方法声明如下:

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

这告诉我们,当您初始化 Firebase 应用程序时,它会使用标识实例的名称进行初始化。

initializeApp 方法声明如下:

/**
 * 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.
 *
 * @example
 * ```javascript
 *
 * // Initialize default app
 * // Retrieve your own options values by adding a web app on
 * // https://console.firebase.google.com
 * initializeApp({
 *   apiKey: "AIza....",                             // Auth / General Use
 *   authDomain: "YOUR_APP.firebaseapp.com",         // Auth with popup/redirect
 *   databaseURL: "https://YOUR_APP.firebaseio.com", // Realtime Database
 *   storageBucket: "YOUR_APP.appspot.com",          // Storage
 *   messagingSenderId: "123456789"                  // Cloud Messaging
 * });
 * ```
 *
 * @example
 * ```javascript
 *
 * // Initialize another app
 * const otherApp = initializeApp({
 *   databaseURL: "https://<OTHER_DATABASE_NAME>.firebaseio.com",
 *   storageBucket: "<OTHER_STORAGE_BUCKET>.appspot.com"
 * }, "otherApp");
 * ```
 *
 * @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;

这告诉我们,如果您调用 initializeApp 而不提供实例名称作为第二个参数,则将使用该名称生成实例“[DEFAULT]”

最终,这意味着除非您手动命名 Firebase 应用实例,否则在调用 getFirestore 时无需传递它。它将能够获取您的单个主应用程序实例并在必要时使用它。

手动将应用实例传递给 getFirestore 与让 Firestore 直接通过 firebase/app 包获取实例之间应该没有任何区别

I went snooping through the source code to see exactly what was going on and here's what I found:

The code for the getFirestore method is as follows:

/**
 * Returns the existing {@link Firestore} instance that is associated with the
 * provided {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new
 * instance with default settings.
 *
 * @param app - The {@link @firebase/app#FirebaseApp} instance that the returned {@link Firestore}
 * instance is associated with.
 * @returns The {@link Firestore} instance of the provided app.
 */
function getFirestore(app$1 = app.getApp()) {
    return app._getProvider(app$1, 'firestore').getImmediate();
}

If you don't pass an app instance to the function then it sets the app variable to app.getApp().

Earlier in the code, app is defined as require("@firebase/app") and so we need to look at the getApp method in that package.

The getApp method declaration is as-follows:

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

What this tells us is that when you initialize a firebase app, it gets initialized with a name that identifies the instance.

The initializeApp method declaration 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.
 *
 * @example
 * ```javascript
 *
 * // Initialize default app
 * // Retrieve your own options values by adding a web app on
 * // https://console.firebase.google.com
 * initializeApp({
 *   apiKey: "AIza....",                             // Auth / General Use
 *   authDomain: "YOUR_APP.firebaseapp.com",         // Auth with popup/redirect
 *   databaseURL: "https://YOUR_APP.firebaseio.com", // Realtime Database
 *   storageBucket: "YOUR_APP.appspot.com",          // Storage
 *   messagingSenderId: "123456789"                  // Cloud Messaging
 * });
 * ```
 *
 * @example
 * ```javascript
 *
 * // Initialize another app
 * const otherApp = initializeApp({
 *   databaseURL: "https://<OTHER_DATABASE_NAME>.firebaseio.com",
 *   storageBucket: "<OTHER_STORAGE_BUCKET>.appspot.com"
 * }, "otherApp");
 * ```
 *
 * @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;

And that tells us that if you call initializeApp without providing a name for the instance as the second parameter then the instance will be generated with the name "[DEFAULT]"

Ultimately this means that unless you're manually naming your firebase app instance you don't need to pass it in when you call getFirestore. It will be able to fetch your single primary app instance and use it where necessary.

There shouldn't be any difference between passing the app instance to getFirestore manually v.s. letting Firestore get the instance directly through the firebase/app package

银河中√捞星星 2025-01-18 15:32:36

如果您只需要使用一个 Firebase 应用程序,您可以选择其中之一,但如果您有多个应用程序,则需要初始化每个应用程序,为其提供配置并获取其特定的 Firestore。

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

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

仅当您的上下文中有一个已初始化的 Firebase 应用程序并且只有一个时才有效。

如果您希望拥有多个 Firebase 应用程序,则需要初始化每个应用程序并指定您要尝试访问的 Firestore。

通过做

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);
connectFirestoreEmulator(db, 'localhost', 8080);

If you only need to use a single Firebase app you can do either one, but if you have multiple apps, you need to initialize each of them giving them their configs and getting their specific firestore.

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

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

Only works if you have an already initialized firebase app in your context and that there is only one.

If you wish to have more than one firebase app you need initialize each of them and specify what firestore you are trying to access.

By doing

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);
connectFirestoreEmulator(db, 'localhost', 8080);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文