从Firebase的云功能中的Firestore触发器获取用户ID?

Gab*_*ssa 11 node.js firebase google-cloud-platform google-cloud-functions google-cloud-firestore

在下面的示例中,有没有办法获取写入'offers/{offerId}'的用户的用户ID(uid)?我试着像这里描述的那样做,但它在Firestore中不起作用.

exports.onNewOffer = functions.firestore
  .document('offers/{offerId}')
  .onCreate(event => {
    ...
});
Run Code Online (Sandbox Code Playgroud)

小智 20

我在这方面挣扎了一段时间,最后联系了火力支援部门:

我试图实现这一目标.

event.auth.uid是在公司的FireStore数据库触发器事件对象不确定.(适用于实时数据库触发器)

当我在输出中console.log(event)找不到任何内容auth时.

官方支持回答:

抱歉,尚未在Firestore SDK中添加身份验证.我们将它列在下一个功能中.

如有任何进一步的更新,请留意我们的发行说明.

我希望这能节省几个小时.

  • 这是一个未解决的问题:https://github.com/firebase/firebase-functions/issues/300#issuecomment-428421203 (2认同)
  • Firestore 永远不会实现 auth 对象:( https://github.com/firebase/firebase-functions/issues/300#issuecomment-465471983 (2认同)

Eth*_*han 7

我如何解决这个问题的总结/一个可行的解决方案:

在客户端

将登录/当前用户的 uid(例如 as creatorId)添加到他们正在创建的实体中。通过将firebase.auth().onAuthStateChanged()User 对象存储在您的应用程序状态中来访问此 uid 。

在 Firebase Firestore/数据库中

添加安全规则以create验证客户端提供的creatorId值是否与经过身份验证的用户的 uid 相同;现在您知道客户端不会欺骗creatorId并且可以在其他地方信任此值。

例如

match /entity/{entityId} {
  allow create: if madeBySelf();
}

function madeBySelf() {
  return request.auth.uid == request.resource.data.creatorId;
}
Run Code Online (Sandbox Code Playgroud)

在 Firebase 函数中

onCreate向您创建的实体类型添加一个触发器,以使用客户端提供的、现在已验证的实体creatorId来查找创建用户的个人资料信息,并将此信息关联/附加到新实体文档。

这可以通过以下方式实现:

  1. 创建新帐户时创建users集合和单个user文档,并user使用应用程序有用的字段(例如displayName)填充新文档。这是必需的,因为 Firebase 身份验证系统公开的字段不足以供消费者应用程序使用(例如, displayName并且avatarURL未公开),因此您不能仅仅依赖于以这种方式查找创建用户的信息。

    例如(使用 ES6)

import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'

const APP = admin.initializeApp()

export const createUserRecord = functions.auth.user()
  .onCreate(async (userRecord, context) => {
    const userDoc = {
      id: userRecord.uid,
      displayName: userRecord.displayName || "No Name",
      avatarURL: userRecord.photoURL || '',
    }
    return APP.firestore().collection('users').doc(userRecord.uid).set(userDoc)
  })
Run Code Online (Sandbox Code Playgroud)
  1. 既然您有一个经过验证的creatorId值和有用的user对象,请onCreate向您的实体类型(或您创建的所有实体)添加一个触发器,以查找创建用户的信息并将其附加到创建的对象中。
export const addCreatorToDatabaseEntry = functions.firestore
  .document('<your entity type here>/{entityId}')
  .onCreate(async (snapshot, context) => {
    const userDoc = await APP.firestore().collection('users').doc(snapshot.data().creatorId).get()
    return snapshot.ref.set({ creator: userDoc.data() }, { merge: true })
})
Run Code Online (Sandbox Code Playgroud)

这显然会导致整个系统中出现大量重复的用户信息数据——您可以做一些清理工作(在上述实现中创建的实体上重复了“creatorId”)——但现在它非常容易显示谁在整个应用程序中创建了什么,并且似乎是“Firebase 方式”。

希望这可以帮助。我发现 Firebase 在某些方面非常出色,并且让一些通常简单的事情(比如这样)变得比它们“应该”更难;总的来说,虽然我是一个大粉丝。


ask*_*ndz 5

在将其添加到 firestore 函数之前,解决方法是user_id在创建文档时将其添加为字段,然后删除。然后,您可以在 onCreate 函数中获取它,然后在将其用于您需要的用途后,在该函数中,只需从该文档中删除该字段即可。


phi*_*ipp 5

文件明确指出,context.auth参数是只在实时数据库中。

此字段仅为实时数据库触发器和可调用函数填充。对于未经身份验证的用户,此字段为空。对于不提供用户信息的 Firebase 管理员用户和事件类型,此字段不存在。

我个人意识到我的数据路径中已经有了 userId。

export const onCreate = functions.firestore.document('docs/{userId}/docs/{docId}')
    .onCreate((snapshot, context) => {
        const userId = context.params.userId;
Run Code Online (Sandbox Code Playgroud)