使电子邮件在 Firebase 身份验证和数据库之间保持同步

Keeping emails synchronized between Firebase auth and database

我将 Firebase Web 用于 SaaS 解决方案。我的目的是随时访问用户的电子邮件,用于发送通知或从后端触发警报。

出于安全原因,Firebase 身份验证不允许列出用户的电子邮件或根据用户 ID 获取电子邮件。因此,在创建用户帐户时,我将电子邮件的副本保存到 Firebase 数据库中的特定集合中。该副本由创建用户时触发的云功能创建(遵循准则:https://firebase.google.com/docs/auth/extend-with-functions)。

感谢 Firebase 数据库中可用的副本,我可以访问用户的电子邮件。但是,我的问题是当用户更改他的电子邮件时。

Firebase 身份验证提供 updateEmail 功能,returns 一个承诺。我最后使用它来更新 Firebase 身份验证中的电子邮件。然后,当承诺解决时,我更新 Firebase 数据库中的用户电子邮件。然而,这有一个主要缺点:所有逻辑都在客户端执行,并且如果客户端刷新或关闭他的浏览器(或假设它崩溃),由于这两个操作都不会在事务中执行,那么 Firebase 身份验证可能是已更新但未更新 Firebase 数据库,从而导致状态不一致。

我看了文档,希望在更新用户授权信息时能够触发云功能。很遗憾,我找不到这样的功能。

我想到的另一个解决方案是从 Web 客户端更新数据库。然后,这最后会触发一个 Cloud 函数,该函数使用 updateEmail 执行的 admin SDK. This last solution works but bypasses the check performed by updateEmail that ensures the new email is not used by another account. Also, the account hijacking protection 更新 Firebase 身份验证被逐出,从安全角度来看,这确实很糟糕。

欢迎任何正确解决此问题的想法。

这里有几个选项:

  1. 调用updateEmail时,在调用updateEmail之前先更新数据库中的电子邮件。但是,如果发生错误,您需要捕获它并撤消数据库中的更改。

  2. 当用户想要更新电子邮件时,将他们的 ID 令牌和新电子邮件发送到您的服务器或 firebase 函数 http 端点。在那里,您使用管理 SDK 验证 ID 令牌,然后使用客户端 SDK require('firebase'),使用来自 ID 令牌的 uid,admin.auth().createCustomToken(uid),然后使用客户端 SDK,firebase.auth().signInWithCustomToken(customToken)。然后您可以在后端调用 user.updateEmail(newEmail) 并保存电子邮件。

  3. 始终仅保存 uid,仅使用 Admin SDK admin.auth().getUser(uid) 查找用户并获取他们的电子邮件。这可以保证您收到用户的最新电子邮件,因为如果用户选择这样做,您将无法收到电子邮件撤销。

  4. 不需要保存任何东西。使用 CLI SDK 下载您的所有用户及其电子邮件。检查 https://firebase.google.com/docs/cli/auth#authexport 这也更好,因为即使他们撤销了电子邮件更改,您也始终能够获得每个用户的最新电子邮件。