关联您的应用并开始原型设计


在开始使用 Firebase Local Emulator Suite 之前,请确保先根据适用于您的平台(AppleAndroidWeb)的 Firebase 使用入门主题,为您的平台创建了 Firebase 项目、设置了开发环境,并选择和安装了 Firebase SDK。

原型设计和测试

Local Emulator Suite 包含多个产品模拟器,如 Firebase Local Emulator Suite 简介中所述。您可以根据生产环境中使用的 Firebase 产品,自由地使用单个模拟器或多个模拟器的组合进行原型设计和测试。

Firebase 数据库与 Functions 模拟器之间的交互
数据库和 Cloud Functions 模拟器是完整的 Local Emulator Suite 的一部分。

在本主题中,为了介绍 Local Emulator Suite 工作流,我们假设您正在开发的应用使用的是典型产品组合:Firebase 数据库以及由该数据库上的操作触发的 Cloud Functions 函数。

在本地初始化 Firebase 项目后,使用 Local Emulator Suite 的开发周期通常分为三个步骤:

  1. 使用模拟器和 Emulator Suite UI 以交互方式进行功能原型设计。

  2. 如果您使用的是数据库模拟器或 Cloud Functions 模拟器,请执行一次性步骤以将应用连接到模拟器。

  3. 使用模拟器和自定义脚本自动执行测试。

在本地初始化 Firebase 项目

请确保您已安装 CLI已将其更新到最新版本

curl -sL firebase.tools | bash

请将当前的工作目录初始化为 Firebase 项目,按照屏幕上的提示,指明您正在使用 Cloud Functions 以及 Cloud FirestoreRealtime Database(如果您尚未执行此操作):

firebase init

您的项目目录现在将包含 Firebase 配置文件、适用于数据库的 Firebase Security Rules 定义文件、包含 Cloud Functions 函数代码的 functions 目录,以及其他支持文件。

以交互方式进行原型设计

Local Emulator Suite 旨在让您快速进行新功能原型设计,其内置界面是最有用的原型设计工具之一。该界面有点像在本地运行 Firebase 控制台。

使用 Emulator Suite UI,您可以迭代数据库的设计,试用涉及 Cloud Functions 函数的不同数据流,评估安全规则更改,检查日志以确认后端服务的执行情况等等。如果您想重新开始,只需清除数据库并重新开始设计。

您可以使用以下命令启动 Local Emulator Suite

firebase emulators:start

为了设计我们假设的应用的原型,我们要设置并测试一个基本 Cloud Functions 函数以修改某个数据库中的文本条目,然后在 Emulator Suite UI 中创建并填充该数据库以触发该函数。

  1. 修改项目目录中的 functions/index.js 文件,创建一个由数据库写入操作触发的 Cloud Functions 函数。将现有文件的内容替换为以下代码段。此函数监听对 messages 层次结构中节点的更改,将节点的 original 属性的内容转换为大写,并将结果存储在该节点的 uppercase 属性中。
  2.   const functions = require('firebase-functions/v1');
    
      exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
          .onCreate((snapshot, context) => {
            const original = snapshot.val();
            console.log('Uppercasing', context.params.pushId, original);
            const uppercase = original.toUpperCase();
            return snapshot.ref.parent.child('uppercase').set(uppercase);
          });
      
  3. 使用 firebase emulators:start 启动 Local Emulator SuiteCloud Functions 和数据库模拟器将启动,并自动配置为可以进行互操作。
  4. 在浏览器中输入以下网址查看界面:http://localhost:4000。端口 4000 是界面的默认设置,但请检查 Firebase CLI 输出的终端消息。注意可用模拟器的状态。在我们的示例中,Cloud FunctionsRealtime Database 模拟器将运行。
    我的图片
  5. 在界面中的“Realtime Database”标签页上,使用数据库内容编辑器控件创建一组节点,其中 messages 节点包含一个 message1 节点,而该节点又包含一个键设置为 original、值设置为 test 的节点。这会触发我们的 Cloud Functions 函数。随即会出现新的 uppercase 属性,值为 TEST
    我的图片 我的图片
  6. 检查“日志”标签页,确认您的函数在更新数据库时没有出现错误。

您可以轻松地在 Cloud Functions 函数代码与交互式数据库修改之间进行迭代,直到使数据流符合您的期望,而无需改动应用内数据库访问代码、重新编译和重新运行测试套件。

将应用连接到模拟器

使用交互式原型设计取得进展并确定最终设计后,您就可以使用相应的 SDK 向应用添加数据库访问代码了。您将继续使用数据库标签页。对于函数,请使用 Emulator Suite UI 中的“日志”标签页确认应用的行为正确无误。

请注意,Local Emulator Suite 是本地开发工具。向生产数据库写入数据不会触发您在本地进行原型设计的函数。

如需改为让您的应用对数据库执行写入操作,您需要将测试类或应用内配置指向 Realtime Database 模拟器。

Kotlin+KTX
// 10.0.2.2 is the special IP address to connect to the 'localhost' of
// the host computer from an Android emulator.
val database = Firebase.database
database.useEmulator("10.0.2.2", 9000)
Java
// 10.0.2.2 is the special IP address to connect to the 'localhost' of
// the host computer from an Android emulator.
FirebaseDatabase database = FirebaseDatabase.getInstance();
database.useEmulator("10.0.2.2", 9000);
Swift
    // In almost all cases the ns (namespace) is your project ID.
let db = Database.database(url:"http://127.0.0.1:9000?ns=YOUR_DATABASE_NAMESPACE")

Web

import { getDatabase, connectDatabaseEmulator } from "firebase/database";

const db = getDatabase();
if (location.hostname === "localhost") {
  // Point to the RTDB emulator running on localhost.
  connectDatabaseEmulator(db, "127.0.0.1", 9000);
} 

Web

var db = firebase.database();
if (location.hostname === "localhost") {
  // Point to the RTDB emulator running on localhost.
  db.useEmulator("127.0.0.1", 9000);
} 

使用自定义脚本自动执行测试

现在,我们来看看最后一个总体工作流程步骤。在对应用内功能进行原型设计并且您的应用看起来在所有平台上都有望成功后,您就可以开始进行最终实现和测试了。对于单元测试和 CI 工作流,您可以使用 exec 命令在单个调用中启动模拟器、运行脚本测试并关闭模拟器:

firebase emulators:exec "./testdir/test.sh"

深入探索各个模拟器

现在您已经了解了基本的客户端工作流,可以继续了解该套件中的各个模拟器的详细信息,包括如何用其进行服务器端应用开发:

后续步骤

请务必阅读上述链接中与特定模拟器相关的主题。然后: