Firebase-tools: 将 firebase 身份验证模拟器添加到模拟器套件

创建于 2019-09-26  ·  66评论  ·  资料来源: firebase/firebase-tools

是否可以模拟身份验证 API 以加快本地开发和端到端测试? 使用 Firestore 模拟器,我们不必为不同的环境(开发、测试、登台、生产)创建不同的项目,我们只需使用模拟器,在监视模式下从 JSON 文件向其播种数据以进行开发,或者为每个项目播种测试用例等。为了能够编写具有用户登录、基于角色的导航以及一些操作的端到端测试,我们必须创建一个单独的项目来隔离测试用户,并在那里播种和清除用户对于每个测试用例。

emulator-suite feature request

最有用的评论

我们正在努力开发一个完整的身份验证模拟器,这有望成为
大家都想。 我现在无法提供时间表,但这是一个高度优先事项
为我们。

2020 年 5 月 22 日星期五上午 8:12,ChuckB [email protected]写道:

@samtstern https://github.com/samtstern任何进展或其他
此问题/功能的解决方案? 我需要 (1) setEmulatedUser 来使用
云 Firestore 模拟器,以便我可以在本地进行手动测试。

根据您的评论:2019 年 10 月 17 日
_我认为显然(2)是正确的故事,但我试图了解
有多少人会对 (1) 感到满意,因为它要简单得多
实施和维护。

(1) 无需登录即可使用 Firestore 或实时数据库等服务
真正创造真正的用户。 现在就是这样
setEmulatedUser 将解决。 它只会让你有一个虚假的身份验证
模拟器将接受但会被拒绝的本地令牌
产品。 更安全、更多隔离等_


你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/firebase/firebase-tools/issues/1677#issuecomment-632660684
或取消订阅
https://github.com/notifications/unsubscribe-auth/ACATB2Q4LV7NXMQFEALNPXLRSZT25ANCNFSM4I27PTFA
.

所有66条评论

@vladimirdjurdjevic感谢您提出这个问题! 这是我们要做的事情列表,但我们尚未决定要模拟多少身份验证服务以及执行此操作的最佳策略。 某些事情(例如匿名身份验证)很容易模拟,而其他事情(例如 SMS 身份验证)则非常困难。

但我们绝对希望启用您提到的端到端用例!

问题:如果有一个库允许您在本地模拟 Firebase 用户以与模拟器一起使用,您会觉得它有用吗? 就像是:

firebase.auth().setEmulatedUser({
   uid: 'abc123',
   // ...
});

@samtstern调用setEmulatedUser()也会触发任何functions.auth.user().onCreate()模拟云函数? 如果是这样,那将非常有用。

@samtstern这肯定会帮助一些测试场景,但仍然需要真实的开发实例。 我的想法是避免为不同的环境创建多个 firebase 项目,并且能够在本地(可能是离线)开发。 另一种方法是支持不同的服务环境。 如果我们可以为同一个项目下的 firestore 和 auth 创建不同的环境,它将解决很多问题。 我知道我可以为每个环境创建项目,但这真是太麻烦了。 配置每个环境,复制数据等。理想情况下,我希望能够创建一个 firebase 项目,如果我需要虚拟数据进行手动测试,我可以为 firestore 创建一个临时环境,并在那里上传数据。

@noelmansour好问题! 这样做并不难,我们可能需要两个不同的调用,如signInAsEmulatedUsersignUpAsEmulatedUser ,其中只有第二个调用触发函数。

@vladimirdjurdjevic完全同意全功能模拟器是最好的。 您能否解释一下“真实的开发实例”中您需要哪些不能通过本地设置用户解决的问题?

问题:如果有一个库允许您在本地模拟 Firebase 用户以与模拟器一起使用,您会觉得它有用吗?

真的很有用,会有很大帮助。
现在我只是将规则函数设置为true每次我必须在本地测试某些内容时验证登录的用户,这很不安全,但可能是我可以在不模拟当前用户的情况下做的更简单的事情。

是的,这将非常有用

我也想单元测试functions.auth.user().onCreate() 。 我想现在最好的解决方法本质上是导出回调函数传递给onCreate并提供假的user对象给它。

对于那种单元测试,请查看 firebase-function-test
库,它可以帮助您使用模拟数据调用函数处理程序。

2019 年 10 月 13 日,星期日,上午 5:44,Daniel K. [email protected]写道:

我还想对functions.auth.user().onCreate() 进行单元测试。 一世
假设现在最好的解决方法本质上是导出回调
函数传递给 onCreate 并为其提供假用户对象。


你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/firebase/firebase-tools/issues/1677?email_source=notifications&email_token=ACATB2QYJLX2LNVDTWJV25TQOMJ4VA5CNFSM4I27PTFKYY3PNVWWK3TUL52HS4DFVREXG43MVVMVBWZKLONTV43MVVBWZKLON543MVVBWZKLON543MVWWZKLOMTW1VWWWZQLOM55C43VWWZKLON51
或取消订阅
https://github.com/notifications/unsubscribe-auth/ACATB2SO3IR6UB73F4EMZPTQOMJ4VANCNFSM4I27PTFA
.

@samtstern这实际上与 Firestore 模拟器一起工作吗? 基于此,我得到的印象是它用于不同的目的。

image
https://firebase.google.com/docs/functions/unit-testing#initializing

我当然不想要单元测试的在线模式,那会很慢。 而且我不确定是否可以通过“存根”访问 Firestore 模拟器。

@FredyC感谢您指出这些文档。 使用的词令人困惑,因为“模式”不是您可以启用的开关,它们只是描述您可以采取的策略。

如果您要在单元测试的同时启动 Firestore 模拟器,您的代码肯定可以连接到它。 如果您设置FIRESTORE_EMULATOR_HOST环境变量,Firebase Admin SDK 将自动连接到 Firestore 模拟器( firebase emulators:exec会为您执行此操作)。

@samtstern我仍然无法连接点,这一切如何帮助我测试functions.auth.user().onCreate() ? 我的意思是功能可以连接到模拟器而不是生产版本很棒,但这只是 Firestore,对吗? 如何从测试中调用用户创建以实际启动功能代码?

在提到的 firebase-functions-test 中似乎有一些神秘的方法makeUserRecord ,但它如何工作或如何实际使用它没有多大意义。

我尝试从@firebase/testing包中调用auth.createUserWithEmailAndPassword() ,但这抱怨无效的 API 密钥,因此我认为它仅适用于在线版本。

当我在 org 中搜索您提到的那个 env 变量时,它只在三个地方,似乎没有一个与 auth 真正相关。 除非它被一些字符串连接隐藏。

我也一直在浏览https://github.com/firebase/functions-samples,但我没有在那里找到单元测试的例子。

你能理解一下吗? :)

我还有另一种情况,有点相反,其中云函数代码使用admin.auth().getUserByEmail()调用。 令人惊讶的是,它并没有以错误结束,但我不知道如何创建该用户以便可以返回它。 当然,除了模拟整个管理模块,但这太疯狂了:)

@samtstern抱歉耽搁了。 当我说真实实例时,我指的是真实实例 :D 理想情况下,我只想在我的 angular 环境文件中交换配置以进行开发,并继续实现身份验证功能,例如我的应用程序正在与真实 API 对话,但它实际上是在我的模拟器上运行机,我可以离线完成。 现在,我了解发送短信的挑战。 期望模拟器向我的手机发送真正的 SMS 是愚蠢的,但您也许可以将它打印到控制台(将发送的 SMS 的内容)。 这可能比它的价值更麻烦。 这就是为什么我认为只支持每个项目的多个环境可以使事情变得更好。 在不同环境的多个项目之间复制配置需要很多时间。 而且,管理脚本的多个服务帐户以便能够将数据播种到不同的 Firestore 项目也很痛苦。 这就是为什么我教导说,如果我们模拟了一个完整的 Firebase 平台,我们可以将它用于每个非生产环境,并且只管理一个真正的 Firebase 项目。 但也许只支持每个项目的多个环境是一个更好的解决方案,结果可以接受。

@FredyC感谢您的所有反馈! 看看这有多令人困惑,这对我们很有帮助。 人们在与身份验证相关的测试中主要想做两件事:

  1. 登录以使用 Firestore 或实时数据库等服务,而无需实际创建真实用户。 现在这就是setEmulatedUser类的东西可以解决的问题。 它只会允许您在本地拥有一个仿真器会接受的虚假身份验证令牌,但它会被产品拒绝。 更安全、更隔离等。
  2. 实际上直接测试认证。 这将有几个部分:
    一种。 一个 auth 模拟器,它响应所有必要的 API 调用,以便您可以将 Auth SDK 指向它。
    湾该模拟器和函数模拟器之间的集成,以便正确触发.onCreate函数。
    C。 在函数模拟器中自动模拟,以便admin.auth()指向 Auth 模拟器,就像我们今天对 Firestore 和 RTDB 所做的一样。

我认为显然 (2) 是正确的故事,但我试图了解有多少人会对 (1) 感到满意,因为它的实施和维护要简单得多。

@samtstern我明白了。 如果我错了,请纠正我,但(1)不是已经解决了吗? 我的意思是在测试中,我可以只调用以下内容,Firestore 模拟器会将我识别为该用户,因此我可以根据安全规则进行测试。 我还没有真正尝试过,但到目前为止看起来很有希望:)

  const app = firebase.initializeTestApp({
    projectId,
    auth: {
      uid: 'owner'
    }
  })

(2) 听起来确实非常有用,但肯定要复杂得多。 遗憾的是,我对完整产品的了解非常有限,我无法在这里提供任何有用的想法。

我认为它应该逐步构建。 与其试图一次涵盖所有场景,不如根据已知用例构建它并随时添加。 在我有限的意见中,模拟“用户数据库”和函数触发器似乎并不难。

@FredyC你是对的,(1) 已解决,可在测试套件中使用。 但另一个用例实际上是将您的 Android/iOS/Web 应用程序直接连接到模拟器进行本地开发。 在这种情况下,您不能使用@firebase/testing

我知道了。 老实说,如果@firebase/testing可以跨平台使用而不是单独的解决方案,那就太好了。 我的意思是将通信重定向到模拟器有多难? 不正是FIRESTORE_EMULATOR_HOST吗? 虽然我认为像FIREBASE_EMULATOR_HOST这样的东西如果模拟器也有其他服务会更合适。

@vladimirdjurdjevic我在想,基本上模拟signInWithPhone方法实际上不会起作用,以便您可以控制其行为? 那么你就不需要担心模拟器和在控制台中获取模拟的 SMS 代码了 :)

当然,那么您需要某种方式向 Firestore 模拟器进行身份验证(并连接到它)。 就像我在之前的https://github.com/firebase/firebase-tools/issues/1677#issuecomment -542897671 中概述的那样。 有一种生成不安全令牌的底层方法: https :

当然,mock 3rd 方库并不总是那么容易,但是一旦弄清楚,它可以带来很好的结果。 最终,它可以被提取到某个库中以使其更容易。

我还认为这些 signIn 方法会抛出大量错误代码,这也是适当的测试应该注意的问题。 使用模拟也很容易做到这一点。

@samtstern使用诸如setEmulatedUser类的主题扩展firebase.auth()命名空间上下文似乎是现有仿真策略的反模式。 该建议是否可能受到包方面的易于扩展性的影响?

与其他模拟器一致,我希望通过 HTTP 启动一个单独的身份验证服务层,并且客户端配置可以重定向现有的 API 表面以供使用。

我宁愿让古怪的 AuthN 案例返回错误,管理和客户端 API 最低限度地支持基本用户通过用户名/密码的 CRUD。 哎呀,我认为即使从管理员和signInWithCustomToken中的自定义令牌支持开始也会走得很远。 也许使用文档中发布的 API 支持矩阵来实现低垂的果实。

对于@FredyC 的观点,集成身份验证测试的当前策略是有条件地导入应用程序代码中的@firebase/testing以路由到自定义initializeTestApp调用。 此操作既强调项目团队在构建时的包排除,也将模拟器重定向配置分布到两个包 API( initializeTestAppfirestore.settings / functions.useFunctionsEmulator

入侵地球!

当前集成身份验证测试的策略是有条件地导入应用程序代码中的@firebase/testing以路由到自定义initializeTestApp调用。

嗯,我在测试中调用该方法。 诀窍是常规initializeApp驻留在导入函数的index.ts中。 它在模拟器启动时被调用,但是当测试正在执行时,它是一个不同的过程,并且不会相互冲突。 所以真的没有条件导入的负担。

当然,这对于在 eg 中测试身份验证可能会有所不同。 Web 应用程序,其中测试运行器将与应用程序代码共享流程。 但是,通过单元测试,您通常不会将整个应用程序导入到测试中。 initializeApp可能是在一些与测试无关的代码中完成的,根本没有导入。

@FredyC同意单元测试的文档用法。 真正谈到了 API 发散和动态导入脱离记录地图的完整应用程序场景。

我只是想告诉你Honestly, it would be kinda superb if @firebase/testing could be used cross-platform instead of having separate solutions归属。 数字高五

@FredyC感谢您的所有反馈! 看看这有多令人困惑,这对我们很有帮助。 人们在与身份验证相关的测试中主要想做两件事:

  1. 登录以使用 Firestore 或实时数据库等服务,而无需实际创建真实用户。 现在这就是setEmulatedUser类的东西可以解决的问题。 它只会允许您在本地拥有一个仿真器会接受的虚假身份验证令牌,但它会被产品拒绝。 更安全、更隔离等。
  2. 实际上直接测试认证。 这将有几个部分:
    一种。 一个 auth 模拟器,它响应所有必要的 API 调用,以便您可以将 Auth SDK 指向它。
    湾该模拟器和函数模拟器之间的集成,以便正确触发.onCreate函数。
    C。 在函数模拟器中自动模拟,以便admin.auth()指向 Auth 模拟器,就像我们今天对 Firestore 和 RTDB 所做的一样。

我认为显然 (2) 是正确的故事,但我试图了解有多少人会对 (1) 感到满意,因为它的实施和维护要简单得多。

@samtstern首先我会❤️有这种模拟。

我会看没有。 1 对于编写 e2e 测试非常有用。 目前我必须使用真实实例进行身份验证,而我可以使用模拟器进行托管、规则、firestore 和函数。

我认为应该可以使用 setEmulatedUser 以与在 firebase.initializeTestApp 中完成的方式相同的方式模拟用户。 应该可以提交例如自定义令牌和其他用户相关数据。

还应该可以使用firebase.auth().signInWithCredential(credential)获取可在客户端应用程序中使用的示例凭据

感谢@vladimirdjurdjevic提出这个问题! 我们寻找解决方案已经将近一年了。

我们希望看到一个真正的模拟器,用于三件事:

  1. 整个应用程序的 e2e 测试,因此我们不必像@vladimirdjurdjevic所说的那样创建不同的环境。
  2. 后端的集成测试,其中调用 API 并且应在 Firebase 验证用户。
  3. 我们所有的开发人员在开发过程中都使用中央 Firebase 环境,这会导致大量冲突。 当然,每个开发人员都可以创建自己的 Firebase 项目,但他们仍然需要在 Firebase 仪表板中管理他们的测试用户,这并不理想。 此外,我们希望离线开发我们的应用程序,这在今天是不可能的,因为缺少真正的模拟器。

我希望你能尽快为我们发布一些东西,它会让你的产品更有价值! 在此类服务中,开发人员的生产力非常重要!

这似乎是许多人的愿望清单上的一个功能。 Firebase 身份验证似乎是目前定价方面排名第一的 IDaaS,因此无法使用 Cloud Functions 在本地进行开发真的很痛苦。 希望FB团队尽快为我们提供更新! 🙏

编辑:来自@ firebase -ops 的 Ping

我也有这个错误...函数被忽略,因为身份验证模拟器不存在或未运行。

这是由以下代码触发的:

函数.auth.user().onDelete()

关于这个的任何信息...

@多米尼克折叠

我同意你的观点。 同时可能对您有所帮助的一个提示:

当然,每个开发人员都可以创建自己的 Firebase 项目,但他们仍然需要在 Firebase 仪表板中管理他们的测试用户,这并不理想。

您可以使用 firebase admin SDK 以编程方式播种和管理用户,例如auth().createUser ,另请参阅https://firebase.google.com/docs/auth/admin/manage-users

阅读此主题后,我认为这里的人可能会发现Foundry很有用。

我是 Foundry 的联合创始人之一。 Foundry 是一个 CLI 工具,可以获取您的 Firebase Cloud Functions 并在我们的服务器上创建您的生产 Firebase 应用程序的副本,这些服务器充当您的开发环境,您可以在其中直接运行您的代码。 无需配置。

Foundry 会监视您的源代码文件,每次您在本地保存代码时,我们都会在我们的服务器上运行它,并在几秒钟内将结果返回给您。 一切都超级快。
您指定应通过我们的 YAML 文件从您的生产应用程序复制哪些 Firestore、RealtimeDB 和 Auth 用户数据,以便在开发过程中使用它们。

 users:
      - getFromProd: 5 # Copy first 5 users from your Firebase project
      - getFromProd: ['id-1', 'id-2'] # Copy users with the specified IDs from your Firebase project

 # Copy first 3 documents from production from the collection 'userWorkspaces'
 # also add a custom document with id 'new-user-workspace' with a new data
 # format that you want to use
 firestore:
     - collection: userWorkspaces
       docs:
         - getFromProd: 3
         - id: new-user-workspace
           data: {"newDataFormat": 42}

您还可以指定我们在运行您的代码时应如何触发您的云功能。 它的工作原理有点像您的云功能的 REPL。 这样,您始终可以确保您的云功能在部署后能够正确处理生产数据并在生产环境中正常工作。
此外,您的云功能就像已部署一样。

这些开发环境是在您开始会话后临时创建的。 因此,您团队中的每个人都在自己的环境中运作,在那里他们可以乱七八糟。

我不想在这里乱发讨论,所以请随时给我发电子邮件
我非常乐意帮助您在您的项目中设置 Foundry,只需给我发送电子邮件!

然而,根据您的描述以及我在主页上阅读的内容,该服务是基于云的。
Firebase 模拟器甚至可以离线工作,因此它对自动测试很有用。

@samtstern此问题/功能有任何进展或其他解决方案吗? 我需要 (1) setEmulatedUser 与云 Firestore 模拟器一起工作,以便我可以在本地进行手动测试。 另一种选择是使用命令行参数在模拟器启动时设置用户 ID。 通过这种方式,模拟器将在启动期间传入的用户 ID 下运行。 通过这种方式,可以在本地测试规则。

根据您的评论:2019 年 10 月 17 日
_我认为显然 (2) 是正确的故事,但我试图了解有多少人会对 (1) 感到满意,因为它的实施和维护要简单得多。

(1) 登录以使用 Firestore 或实时数据库等服务,而无需实际创建真实用户。 现在这就是 setEmulatedUser 之类的东西可以解决的问题。 它只会允许您在本地拥有一个仿真器会接受的虚假身份验证令牌,但它会被产品拒绝。 更安全、更多隔离等_

我们正在努力开发一个完整的身份验证模拟器,这有望成为
大家都想。 我现在无法提供时间表,但这是一个高度优先事项
为我们。

2020 年 5 月 22 日星期五上午 8:12,ChuckB [email protected]写道:

@samtstern https://github.com/samtstern任何进展或其他
此问题/功能的解决方案? 我需要 (1) setEmulatedUser 来使用
云 Firestore 模拟器,以便我可以在本地进行手动测试。

根据您的评论:2019 年 10 月 17 日
_我认为显然(2)是正确的故事,但我试图了解
有多少人会对 (1) 感到满意,因为它要简单得多
实施和维护。

(1) 无需登录即可使用 Firestore 或实时数据库等服务
真正创造真正的用户。 现在就是这样
setEmulatedUser 将解决。 它只会让你有一个虚假的身份验证
模拟器将接受但会被拒绝的本地令牌
产品。 更安全、更多隔离等_


你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/firebase/firebase-tools/issues/1677#issuecomment-632660684
或取消订阅
https://github.com/notifications/unsubscribe-auth/ACATB2Q4LV7NXMQFEALNPXLRSZT25ANCNFSM4I27PTFA
.

1. 登录以使用 Firestore 或实时数据库等服务,而无需实际创建真实用户。 现在这就是 setEmulatedUser 之类的东西可以解决的问题。 它只会允许您在本地拥有一个仿真器会接受的虚假身份验证令牌,但它会被产品拒绝。 更安全、更隔离等。

在此期间,我会对这里的 1 号感到满意

@rishisingh-dev 无法运行身份验证仿真器,因为 Firebase 仿真器目前没有提供。

但是完全有可能测试涉及身份验证的云功能。 您可以重构需要一些身份验证 API 的函数并在测试中模拟它,同时在 firebase 函数文件中提供真实的函数。 您的测试设置的保真度较低,但随后就变成了程度问题,而不是种类问题:您只是直接测试身份验证调用,但您可以测试您期望它们是什么。

在那个SO问题中,它会是这样的:

function sendWelcomeEmail(user) {
  console.log(user.uid);
  console.log(user.email);
  console.log(user.displayName);
}

exports.sendWelcomeEmail = functions.auth.user().onCreate((user) => sendWelcomeEmail(user));

在您的测试中,您可以直接调用sendWelcomeEmail以确保它执行您需要的操作。

想象一下,您有一个更复杂的云函数addFriend ,用户在其中输入朋友的电子邮件并且您需要 uid。 您可以通过 auths getUserByEmail

function addFriend(email, getUserByEmail ) {
  const friendUid = getUserByEmail(email);
  // do things with friendUid;
}

exports.addFriend = functions.https.onCall(async (data, context) => {
  const email = data.email;
  const getUserByEmail = (email) => admin.auth().getUserByEmail(email);
  return { res: await addFriend(email, getUserByEmail ) };
}

在 cloud fn 声明中,您发送的是真实的getUserByEmail ,但在您的测试中,您发送的是假的:

async function testAddFriend() {
  const emails = {"[email protected]": "test-uid")
  const fakeGetUserByEmail = (email) => emails[email];
  addFriend("[email protected]);
  // verify the things were done with friendUid
}

我不觉得这与在单元测试中测试任何第三方 API 有很大不同。 让 firebase 模拟器提供 auth 删除端到端测试场景的样板,但它不会显着改变单元测试,因为无论如何你都不希望在测试之间保持持久状态。

我希望能够在本地运行它而无需上传到云端进行检查

export const onCreate = functions.auth.user().onCreate((user) => {
    addGravatarURLtoUserData(user.uid, user.email)
})

export const addGravatarURLtoUserData = async (uid, email) => {
    const hash = crypto.createHash("md5").update(email).digest("hex")
    await admin.database().ref(`users/${uid}`).update({ gravatarURL: uid })
}

顺便说一下,我可以在 onCreate 函数中获取 user.displayName 吗?

是的,如果设置了,我想,你试过了吗?

是的,它返回空值。
我在云端(不是本地)上试过。

Screen Shot 2020-07-10 at 2 43 12 AM

我的代码在这里。

exports.sendWelcomeEmail = functions.auth.user().onCreate((user) => {
  console.log(user.uid);
  console.log(user.email);
  console.log(user.displayName);
});

有趣的是我不使用 display name ,我使用自定义用户 displayName
实时数据库

/**
 * updates Custom data in the realtime datastore users object, except for the username
 * <strong i="7">@param</strong> data
 * <strong i="8">@returns</strong> {Promise<void>}
 */
export async function updatePersonalData(data) {
    const { displayName } = data
    try {
        await firebase
            .database()
            .ref("users/" + firebase.auth().currentUser.uid)
            .update({
                displayName: displayName,
            })

        userDataStore.update((user) => {
            return { ...user, displayName: displayName }
        })
    } catch (e) {
        alert(e.message)
    }
}

2020 年 7 月 10 日星期五 10:44,rishisingh-dev通知@github.com
写道:

是的,它返回空值。
我在云端(不是本地)上试过。

[图像:屏幕截图 2020-07-10 at 2 43 12 AM]
https://user-images.githubusercontent.com/56976320/87140958-29f3ac80-c257-11ea-98d3-084fad619de7.png

我的代码在这里。

控制台日志(用户。uid);
控制台日志(用户。电子邮件);
console.log(user.displayName);
});```


您收到此消息是因为您订阅了此线程。
直接回复本邮件,在GitHub上查看
https://github.com/firebase/firebase-tools/issues/1677#issuecomment-656587759
或取消订阅
https://github.com/notifications/unsubscribe-auth/AABU35Q27EMMHYAYU5CNZR3R23PIDANCNFSM4I27PTFA
.

>

亲切的问候

尼科斯·卡齐卡尼斯

是的,我的主要目标是使用onCreate函数内的用户信息更新数据库。
但由于我无法得到displayName ,我做了一个onCallable函数,并做到了。

谢谢。

@samtstern我很高兴看到你在做这个 :) 刚刚开始使用 firebase 的新项目,开发体验已经好多了(使用模拟器 ui 和 --inspect-functions 选项)。 期待看到身份验证模拟器的实际应用:) 干得好!

另一个最好的事情是我不必在没有安全性的情况下打开 chrome

@samtstern

两个月后,现在可以给出一个粗略的估计吗?

我们想在明年年初发货。 我们现在面临着决定,是开始针对真实项目编写集成测试,还是等待几个月的身份验证模拟器。 你能帮我们一下吗?

最好的事物,

尼克拉斯

我们在 Firebase 的政策是除非我们 100% 确定,否则不会对某项产品的发布时间进行估计。 现在我们正在努力开发 Auth 模拟器,但我们还没有完成选择发布日期的工作。

这是我们的首要任务之一,但我认为您不应等待我们开始测试您的应用程序。 立即针对 prod 编写测试,并在可用时将它们切换到针对模拟器。

好的,谢谢@samtstern。 这有帮助!

我们真正想要使用身份验证模拟器来测试涉及用户令牌自定义声明的Cloud Functions 和 Firestore 请求。 我们可以在 Firebase 控制台的规则操场中使用 Firestore 测试自定义声明,但一个成熟的身份验证模拟器理论上可以让我们在测试用户令牌时做更多的事情。

需要明确的是:我们致力于打造一个能够模拟实际服务端点(只要可能)的成熟的身份验证模拟器。 我们不再考虑像我之前的评论所建议的

@samtstern

@fandy不抱歉,我们还没有任何东西可以分享...

谢谢山姆,目前我正在手动进行所有测试,因为它不是
值得在没有 Auth 模拟的情况下编写 e2e 测试

2020 年 8 月 26 日星期三 14:32,Sam Stern [email protected]写道:

>
>

@fandy https://github.com/fandy不抱歉我们没有任何东西
还没有分享...


您收到此消息是因为您订阅了此线程。
直接回复本邮件,在GitHub上查看
https://github.com/firebase/firebase-tools/issues/1677#issuecomment-680850282
或取消订阅
https://github.com/notifications/unsubscribe-auth/AABU35UAQDBYEXKKINJSM43SCT6E7ANCNFSM4I27PTFA
.

——

亲切的问候

尼科斯·卡齐卡尼斯

为了解决这个问题,我尝试在浏览器中导入 @firebase/testing。 那真的行不通。 然而,这确实:mangle @firebase/testing source 复制出以下稍微编辑的块:

import firebase from "firebase/app"
import * as component from "@firebase/component"
import * as util from "@firebase/util"
import { __awaiter, __generator } from "tslib"

function createUnsecuredJwt(auth) {
    // Unsecured JWTs use "none" as the algorithm.
    var header = {
        alg: 'none',
        kid: 'fakekid'
    };
    // Ensure that the auth payload has a value for 'iat'.
    auth.iat = auth.iat || 0;
    // Use `uid` field as a backup when `sub` is missing.
    auth.sub = auth.sub || auth.uid;
    if (!auth.sub) {
        throw new Error("auth must be an object with a 'sub' or 'uid' field");
    }
    // Unsecured JWTs use the empty string as a signature.
    var signature = '';
    return [
        util.base64.encodeString(JSON.stringify(header), /*webSafe=*/ false),
        util.base64.encodeString(JSON.stringify(auth), /*webSafe=*/ false),
        signature
    ].join('.');
}

function initializeApp(accessToken, options) {
    var _this = this;
    var app = firebase.initializeApp(options);
    if (accessToken) {
        var mockAuthComponent = new component.Component('auth-internal', function () {
            return ({
                getToken: function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
                    return [2 /*return*/, ({ accessToken: accessToken })];
                }); }); },
                getUid: function () { return null; },
                addAuthTokenListener: function (listener) {
                    // Call listener once immediately with predefined accessToken.
                    listener(accessToken);
                },
                removeAuthTokenListener: function () { }
            });
        }, "PRIVATE" /* PRIVATE */);
        app._addOrOverwriteComponent(mockAuthComponent);
    }
    return app;
}

export function initializeTestApp(options) {
  let accessToken = undefined
  if (options.auth !== undefined) {
    accessToken = createUnsecuredJwt(options.auth)
  }
  return initializeApp(accessToken, options)
}

现在在您的应用程序浏览器端代码中,您可以导入该代码,然后

  let app
  if (dev) {
    app = initializeTestApp({projectId: "test", auth: {uid: "testuser"}})
    app.firestore().settings({
      host: "localhost:8080",
      ssl: false,
    })
  } else {
    app = firebaseProduction.initializeApp({ firebase config here })
    app.firestore().settings({ firestore config here })
  }
  window.firebase = app

效果很好! 现在,当我在开发中运行时,我有一个本地假用户,模拟器认为它是“testuser”(如 firestore 安全规则测试指南所示)。

我使用的另一种解决方法是存根您的身份验证(我使用生成的假用户进行测试)。

打字稿示例:

import type { User as AuthUser } from '@firebase/auth-types'
// not importing a type, but a module of types
import { auth as authTypes} from 'firebase/app'
type Auth = authTypes.Auth

export const authStub = {
    getUser(uid: string) {
        // for uids like `testuser1234uid`
        let n = uid ? uid.replace("testuser", '').replace("uid", '') : ''
        return Promise.resolve({
            uid,
            email: `test.user${n}@foo.com`,
            emailVerified: true,
            providerData: [{
                providerId: 'google.com',
                email: `test.user${n}@foo.com`,
                uid: `testuser${n}provideruid`,
                phoneNumber: null,
                displayName: `Test User ${n}`.trim(),
                photoURL: 'https://thispersondoesnotexist.com/image',
            }],
            metadata: {
                // https://firebase.google.com/docs/reference/admin/node/admin.auth.UserMetadata
                createTime: new Date().toUTCString(),
                lastSignInTime: new Date().toUTCString()
            },
            customClaims: {
                username: `testuser${n}`
            }
        })
    },
    deleteUser(uid: string) {
        return Promise.resolve()
    },
    async updateUser(uid: string, data: AuthUser) {
        let user = await this.getUser(uid)
        return { ...user, data }
    },
    setCustomUserClaims(uid: string, customUserClaims: Object): Promise<void> {
        return Promise.resolve()
    }
}

export const auth = <Auth><unknown>authStub

还要修改您的规则,因为auth.token没有被模拟。 例如:

const rules = fs.readFileSync(__dirname + '/src/firebase/firestore/firestore.rules', 'utf8')
const modifiedRules =
    rules
        .replace(/request\.auth\.token\.email_verified/g, "true")
        .replace(/request\.auth\.token\.firebase\.sign_in_provider/g, "'password'")

await firebase.loadFirestoreRules({ projectId, rules: modifiedRules })

它对我很有用。 希望能帮助到你…

如果您正在关注此线程并愿意成为 Firebase 身份验证模拟器的 Alpha 测试员,请按照以下步骤操作:

  1. 注册 Firebase Alpha 计划: https ://services.google.com/fb/forms/firebasealphaprogram/
  2. 给我发送电子邮件至[email protected] ,确保从您将用于测试的电子邮件地址发送。

请仅在您对试用早期模拟器并提供反馈非常感兴趣时才这样做! 会有错误并且设置的某些部分会很困难,但我们想知道您的想法。

@samtstern这是个好消息! 我很想尝试一下,但我将在本周末之前用我当前的项目进行生产,所以我目前负担不起玩它。 我会尽快注册 alpha 版 :) 感谢您的出色工作。

100% 会想试试这个! 你的男人山姆!

@samtstern期待着尝试并尽我所能提供帮助!

我需要使用 auth 的功能从 Android 本地测试功能,Auth 的上下文始终为 null

好消息,身份验证模拟器是新的8.14.0 版本的一部分! 🙌🎊

谢谢你们的辛勤工作和@samtstern 💪

很棒的家伙!

我只是信使! Auth 模拟器 99% 是由@yuchenshi构建的……这就是为什么我要让他有幸在他醒来时关闭这个问题。

有关于这个新模拟器的任何文档吗? (如何安装、配置客户端等)

PS非常感谢为此所做的所有辛勤工作。 这将为我们提供各种很酷的东西。

@nicoburns很快! 官方公告、文档和所有好东西很快就会发布。

好消息! :) 迫不及待想试一试:)

我知道你一直在等这个,所以让我们切入正题:

**无耻的插件:我今天晚些时候也在做一个关于“如何使用 Firebase 模拟器套件设置 CI”的会议。 在会议时间表上找到它作为练习留给读者。


_P.S. 我真的不能拿 99% 的功劳,因为 Auth Emulator 当然是团队合作。 Firebase 的各种人员和 Firebase 开发人员(您)在这方面也发挥了重要作用。 谢谢!_

@yuchenshi是否可以在退出时导出创建的用户,就像使用 firestore 模拟器一样?

@vdjurdjevic还没有,我们正在努力。

这是一个非常受欢迎的问题,每次更新都会通知 50-100 人。 由于我们现在已经发布了 Auth 模拟器,我将在未来的更新中锁定这个问题。 如果您有问题、错误或功能请求,请开始一个新问题!

此页面是否有帮助?
0 / 5 - 0 等级