【问题标题】:How do I properly configure my iOS application to use the Firebase Local Emulator Suite?如何正确配置我的 iOS 应用程序以使用 Firebase 本地模拟器套件?
【发布时间】:2021-11-19 03:35:25
【问题描述】:

问题

我希望我的 iOS 应用程序连接到我在本地运行的模拟器,并且永远不要绕过模拟器来访问我的生产服务。我已经根据对 Firebase 文档的数小时和数小时的搜索正确配置了所有内容,甚至深入研究了 StackOverflow 问题和 GitHub PR。

目前,我已经为 Auth、Functions 和 Firestore 运行了模拟器。据我所知,主机和端口配置正确。我的本地功能运行良好。我可以使用用户界面。

当我的身份验证代码运行时,它使用我的生产服务进行身份验证,而不是我在本地运行的模拟器套件。它甚至从不承认模拟器套件。

代码片段

在我的模拟器套件的firebase.json 中,我有以下代码:

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "functions": {
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint",
      "npm --prefix \"$RESOURCE_DIR\" run build"
    ]
  },
  "emulators": {
    "auth": {
      "host": "0.0.0.0",
      "port": 9099
    },
    "firestore": {
      "host": "0.0.0.0",
      "port": 8080
    },
    "functions": {
      "host": "0.0.0.0",
      "port": 5001
    },
    "ui": {
      "enabled": true
    }
  }
}

当模拟器套件启动时,我看到以下输出:

┌────────────────┬──────────────┬─────────────────────────────────┐
│ Emulator       │ Host:Port    │ View in Emulator UI             │
├────────────────┼──────────────┼─────────────────────────────────┤
│ Authentication │ 0.0.0.0:9099 │ http://localhost:4001/auth      │
├────────────────┼──────────────┼─────────────────────────────────┤
│ Functions      │ 0.0.0.0:5001 │ http://localhost:4001/functions │
├────────────────┼──────────────┼─────────────────────────────────┤
│ Firestore      │ 0.0.0.0:8080 │ http://localhost:4001/firestore │
└────────────────┴──────────────┴─────────────────────────────────┘

在我的 iOS 应用中,我执行以下操作:

// FirebaseOptions is populated with a GoogleService-Info.plist per environment,
// then passed into this function.
// However, even using FirebaseApp.configure() changes nothing.
private func initialize(options: FirebaseOptions) {
    FirebaseApp.configure(options: options)
    
    // If we aren't running on local emulator, do nothing else.
    guard isRunningLocalEmulator else {
        return
    }
    
    let host = "0.0.0.0"
    
    // Auth
    Auth.auth().useEmulator(withHost: host, port: 9099)

    // Firestore
    let settings = Firestore.firestore().settings
    settings.host = "\(host):8080"
    settings.isPersistenceEnabled = false
    settings.isSSLEnabled = false

    Firestore.firestore().settings = settings
}

附加上下文

  • 我在每个环境中使用多个 GoogleService-Info.plist 文件。但是,我只使用一个 GoogleService-Info.plist 测试了我的代码,以确保这不会导致问题。我的问题没有改变。

链接

我的尝试

  • 同时使用 localhost0.0.0.0 作为我的模拟器主机。
  • 在不同的本地模拟器上运行。
  • 将 Firebase 升级和降级到各种版本,只是为了检查是否有问题。
  • 基于 Xcode 12.5.1 和 Xcode 13 RC 构建。
  • 在 iOS 14.9 和 iOS 15.0 上运行。

问题

  1. 如何初始化 FirebaseApp 使其永远不会包含我的实际项目的任何上下文,这样如果本地仿真因任何原因失败,它将返回错误而不是使用我的生产服务?
  2. 有两种方法可以初始化 Firestore 本地模拟器。我目前正在使用here 显示的sn-p,但还有Firestore.firestore().useEmulator(withHost:port:) 方法,由Auth 服务使用。我不知道哪个更合适。
  3. 为什么我的应用程序一开始就绕过本地模拟器? (也许 1 + 2 会回答这个问题,但我很难过。)

【问题讨论】:

标签: ios firebase google-cloud-firestore firebase-authentication


【解决方案1】:

你用的是什么项目ID?

我问的原因是因为项目 id 的起始 demo- 是为本地(模拟)项目保留的。如果您使用此类,您的仿真会话将永远无法访问云。如果您使用其他任何东西,Firebase(出于某种我不明白的原因)想要使用混合模型。

如何初始化 FirebaseApp,使其永远不会拥有我的真实项目的任何上下文,以便如果本地仿真因任何原因失败,它会返回错误而不是使用我的生产服务?

这就是我对 Q1 的回答。

如果您想了解背景,它源于 Google Cloud Platform (GCP) 约定,其中不允许任何实际项目具有此前缀。 Firebase(在它之上运行)采用了这种约定,并且模拟器 CLI 也意识到了这一点。

它记录在 this subpage 上,但没有我认为的那么相关。

【讨论】:

  • 这实际上也有助于解决问题 3。出于这个原因,我将此标记为首选答案,谢谢!
猜你喜欢
  • 2020-02-29
  • 1970-01-01
  • 2022-07-23
  • 2020-12-02
  • 1970-01-01
  • 2016-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多