> For the complete documentation index, see [llms.txt](https://developers-apps-in-toss.toss.im/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers-apps-in-toss.toss.im/ai-vibe-coding/zh/integration/ji-cheng-firebase.md).

# 集成 Firebase

介绍在 Apps in Toss（迷你应用）WebView 环境中集成 Firebase 的方法。本文档 **Vite(React + TypeScript)** 基于该项目编写。

***

### 概述

Firebase 是提供认证、数据库、文件存储等多种功能的服务。在 Apps in Toss WebView 环境中也可以同样使用，不过， **安全设置和环境变量管理**很重要。

***

### 1. 准备工作

* Firebase 控制台账户（[console.firebase.google.com](https://console.firebase.google.com))
* 用 Vite(React + TypeScript) 制作的项目
* Node.js、npm（或者 yarn、pnpm）

### 2. 创建 Firebase 项目

1. 在 Firebase 控制台中 **创建项目**，即可创建新项目。
2. 项目设置 → **添加应用** → **Web(\</>)** 。
3. 输入应用昵称并注册后，会显示如下配置信息 (firebaseConfig)。

```js
const firebaseConfig = {
  apiKey: '...',
  authDomain: '...',
  databaseURL: '...',
  projectId: '...',
  storageBucket: '...',
  messagingSenderId: '...',
  appId: '...',
  measurementId: '...'
}
```

### 3. 设置环境变量

出于安全考虑，建议将 Firebase 配置信息通过 Vite 环境变量管理。

在项目根目录下 `.env` 文件，并按如下方式编写。

```bash
VITE_FIREBASE_API_KEY=your_api_key
VITE_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your-project-id
VITE_FIREBASE_STORAGE_BUCKET=your-project.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
VITE_FIREBASE_APP_ID=your_app_id
```

在代码中 `import.meta.env.VITE_FIREBASE_API_KEY`这样调用。

### 4. 安装并初始化 Firebase

本文以最新的 Firebase 模块化 SDK(v12+) 为准编写。

```bash
npm install firebase
# 或者
yarn add firebase
```

`src/firebase/init.ts`

```ts
import { initializeApp, getApps } from 'firebase/app'
import { getAuth } from 'firebase/auth'
import { getFirestore } from 'firebase/firestore'
import { getStorage } from 'firebase/storage'

const firebaseConfig = {
  apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
  authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
  projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
  storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
  appId: import.meta.env.VITE_FIREBASE_APP_ID,
}

const app = getApps().length ? getApps()[0] : initializeApp(firebaseConfig)

export const auth = getAuth(app)
export const db = getFirestore(app)
export const storage = getStorage(app)
```

> **注意：**
>
> * `databaseURL`在 **Realtime Database**使用时才需要。如果使用 Firestore，可以省略。
> * `measurementId`在 **Firebase Analytics**（Google Analytics）时需要。

### 5. Firestore 使用示例

如果已初始化 Firestore，就可以在 React 组件中读取或写入数据。下面是 `App.tsx`中读取和保存单个文档的最简单示例。

```tsx
import { useState, useEffect } from 'react'
import { db } from './firebase/init'
import { doc, getDoc, setDoc } from 'firebase/firestore'

function App() {
  const [name, setName] = useState('')
  const [savedName, setSavedName] = useState('')

  // 从 Firestore 读取数据
  useEffect(() => {
    const fetchData = async () => {
      const ref = doc(db, 'users', 'exampleUser')
      const snap = await getDoc(ref)
      if (snap.exists()) {
        setSavedName(snap.data().name)
      }
    }
    fetchData()
  }, [])

  // 向 Firestore 写入数据
  const handleSave = async () => {
    const ref = doc(db, 'users', 'exampleUser')
    await setDoc(ref, { name })
    setSavedName(name)
    setName('')
  }

  return (
    <div style={{ padding: 24 }}>
      <h1>Firestore 简单示例</h1>
      <input
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="输入姓名"
      />
      <button onClick={handleSave}>保存</button>
      <p>已保存的姓名：{savedName || '(无)'}</p>

  )
}

export default App

```

#### 运行方式

* 读取数据（`getDoc`)
  * 只会读取一次 Firestore 中的 users/exampleUser 文档。
  * 如果文档存在，会将 snap.data() 的值显示在画面上。
* 写入数据（`setDoc`)
  * 会将输入的姓名覆盖写入 Firestore。
  * 如果文档不存在，会自动新建。

<figure><img src="https://2480429685-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNbJTp2UkOUSb6YpQegOx%2Fuploads%2FCULa7xVM4LOfxoSSRKB5%2Fimage.png?alt=media&amp;token=c75221bb-940b-4e3a-b718-42d39cdc9a66" alt=""><figcaption></figcaption></figure>

> Firestore 除了单个文档之外，还支持多种功能。
>
> * 实时订阅： `onSnapshot(doc(...))`可在文档发生变更时自动更新 UI。
> * 处理集合： `collection()`, `addDoc()`可以用来添加和读取多个文档。
> * 文件存储： `getStorage()`连接 `Storage`后，可上传图片或文件。
> * 认证联动： `getAuth()`结合使用时，可以按用户分别保存数据。

### 6. 安全检查清单

* 将敏感信息通过环境变量管理
  * Firebase API Key、服务账号密钥等不要直接写在代码里， `.env`请通过环境变量管理。
* 不要将环境文件上传到 Git 等仓库
  * `.env` 请务必将 `.gitignore`中。
  * 如果密钥泄露，请立即在 Firebase 控制台重新签发，并检查相关项目权限。
* 设置 Firebase 安全规则
  * Firestore / Storage 默认对所有用户开放。
  * 发布前务必修改规则，只允许已认证用户访问。
* 确认来源（Origin）限制
  * 请在 Firebase 控制台的 Authentication / Hosting / API Key 设置中限制允许的域名。
  * 只允许迷你应用（WebView）域名，可以防止未授权访问。

{% hint style="info" %}
**允许的目标域名**

```
https://<appName>.apps.tossmini.com : 实际服务环境
https://<appName>.private-apps.tossmini.com : 控制台 QR 测试环境
```

{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers-apps-in-toss.toss.im/ai-vibe-coding/zh/integration/ji-cheng-firebase.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
