Firestore - 云功能 - 获取 uid

Posted

技术标签:

【中文标题】Firestore - 云功能 - 获取 uid【英文标题】:Firestore - Cloud Functions - Get uid 【发布时间】:2018-04-18 04:15:19 【问题描述】:

我正在尝试在云功能中获取通过 firebase web sdk 身份验证的用户的 UID。云功能由云火存储的onWrite 事件触发。

当登录用户创建/更新咖啡馆项目时触发此功能。身份验证由Firebase Auth 处理。安全规则只允许登录用户写入。因此,此事件可能与用户相关联。

export const cfun = functions.firestore.document('cafes/cafeId/items/itemId').onWrite(async event => 
  // trying to get the uid here
)

文档中有处理userId 的示例,但在所有这些情况下,userId 都是文档路径的一部分。但在此模型中,用户不是路径的一部分,因为咖啡馆可能有多个所有者,因此可能被许多用户操纵。因此,将 userId 添加到路径不是一种选择。

这看起来像是无服务器架构的常见案例。

#

更新:由 firestore 触发的函数没有填充 event.auth。寻找有关建模以下要求的建议。

在数据模型中,我有咖啡馆和业主。每个咖啡馆可以由许多所有者拥有,并且可以在稍后阶段将咖啡馆转让给其他所有者。所以咖啡馆被建模为/cafes/cafeId,属于咖啡馆的所有东西都被建模为/cafes/cafeId/items/itemId等。 我们还需要根据不同的参数来查询咖啡馆,如果在用户下面建模就变得困难了。由于这些原因,咖啡馆不能被建模为/users/userId/cafes/cafeId

就安全规则而言,我可以使用get(<>) 来控制写访问,以确定谁可以获得对咖啡馆的写访问。安全性没有问题。

我觉得执行上下文应该提供所有可用的信息,并让开发人员根据他们的用例来处理它。对于无服务器应用程序,userId 是必须的。

如果函数中没有提供event.auth,那么这个限制将强制对不属于用户的项目建模/users/userId/<item_name>/itemId,只是为了访问云函数中的userId。这感觉不自然。

目前还无法确定是否由于控制台中执行的更改而触发了云功能。可用于 firebase 数据库触发函数的 event.auth 信息将非常适合处理所有情况。

对于如何改造这个案例的任何建议也很感激。

#

提前致谢,

【问题讨论】:

每当触发项目创建/更新事件时,尝试设置在项目节点上进行写入的用户的uid 可以从event.auth获取用户。在这里查看雅各布的回答:***.com/questions/42750060/… @FrankvanPuffelen 我测试了 Firestore 触发的功能,但 event.auth 始终未定义。您能否确认此行为是否也适用于云 Firestore。仅供参考,您提到的答案与 firebase 数据库有关。我尝试直接在控制台中进行更改(期望看到admin:true)并使用API​​(期望看到用户信息),在这两种情况下event.auth 都是未定义的。谢谢 您不需要在控制台中执行任何操作。当前用户应该可用。我会四处询问,但您能否编辑您的问题以显示您尝试使用 event.auth 的代码? @FrankvanPuffelen 对此有何更新?谢谢 【参考方案1】:

我也遇到过类似的问题。在 Firebase 中,这很容易——您只需从 event.auth 中获取数据。我会假设这只是我们处于 Firestore 测试阶段时尚未实现的功能。正如您之前提到的那样,将用户 ID 添加到路径中不起作用,因为它会根据进行更新的用户而不断变化。

我的情况是我想在正在更新的对象中创建一个“lastUpdatedBy”字段。如果我们允许客户端在有效负载中发送 lastUpdatedBy 字段,这可能会被流氓客户端(即拥有经过身份验证的帐户的人)滥用,试图冒充其他人。因此,在 Firebase 中,我们依靠云函数来填充数据更改事件的此字段。

我的解决方法是允许客户端插入“lastUpdatedBy”字段,但另外使用 Firestore 规则来验证负载中的 userId 是否与登录用户的匹配 - 否则拒绝写入请求。

类似:

match /collectionA/docId 
  allow update: if request.resource.data.lastUpdatedBy == request.auth.uid;

在 Google/Firestore 的人将“auth”对象添加到云功能之前,我没有看到任何其他解决方法,但希望听到不同的声音。

【讨论】:

是否有任何更新能够检索触发事件的人的 uid?我猜任何对 auth 的引用都会出错,例如 auth.UserInfo() 等。 我也遇到了这个问题,我的付款取决于这个功能。【参考方案2】:

从 Cloud Functions 1.0 开始,您可以像这样获取 UID

exports.dbCreate = functions.database.ref('/path').onCreate((snap, context) => 
  const uid = context.auth.uid;
  const authVar = context.auth; 
);

以下是 FB 团队关于所有 CF1.0 更改的精彩帖子:https://firebase.google.com/docs/functions/beta-v1-diff#event_parameter_split_into_data_and_context

context.auth的数据可以在这里找到:https://firebase.google.com/docs/firestore/reference/security/#properties

【讨论】:

这对 Firestore(不是实时数据库)也正确吗?为实时数据库列出了 context.auth,但没有为 Firestore 列出,当我尝试使用它时出现错误。 console.log(context.auth) 打印“未定义”(2018 年 7 月) 根据 ***.com/a/49827227/280795 和 ***.com/a/49723193/280795 这在 2018 年 6 月的 Firestore 中不起作用 仍然仅适用于 Firebase 数据库,不适用于 Firestore。 Here's the feature request,快来推吧! :) 感谢尤尔根! context.auth.uid 是我需要的! :D

以上是关于Firestore - 云功能 - 获取 uid的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 云功能与 Firestore 返回“已超过截止日期”

使用云功能更新 Firestore 文档

Firebase 云功能 / Firestore

云功能有时会在触发另一个云功能后写入 FireStore

Firestore + 云功能:如何从另一个文档中读取

如何使用云功能从 Firestore 中删除数据