在下面的示例中,有没有办法获取写入'offers / {offerId}'的用户的用户ID(uid)?我尝试按照here所述进行操作,但它在Firestore中不起作用。
exports.onNewOffer = functions.firestore
.document('offers/{offerId}')
.onCreate(event => {
...
});
答案 0 :(得分:16)
我在这方面挣扎了一段时间,最后联系了火力支援部门:
在firestore数据库触发器的事件对象中未定义event.auth.uid
。 (它适用于实时数据库触发器)
当我console.log(event)
时,我在输出中找不到任何auth
。
官方支持回答:
抱歉,尚未在Firestore SDK中添加身份验证。我们将它列在下一个功能中。
请留意我们的发行说明,了解任何进一步的更新。
我希望这可以节省几个小时。
答案 1 :(得分:2)
在将此功能添加到firestore功能之前,解决方法是在创建文档时将user_id
添加为字段,然后删除。然后,您可以在onCreate函数中获取它,然后在将其用于所需内容之后,在函数中,只需删除该文档中的字段。
答案 2 :(得分:2)
如上所述,解决方法是在数据本身中添加一个user_id字段,然后在服务器上读取它。
此方法的缺点是安全漏洞。由于我们没有在服务器上验证用户ID,因此其他任何用户都可以通过向其他用户发送其ID和数据来模拟其他用户。
对于安全性至关重要的应用程序,解决方案将是使用安全性规则来验证是否已将正确的user_id与数据一起发送
allow write: if resource.data.user_id == request.auth.uid;
答案 3 :(得分:2)
documentation明确指出context.auth
参数仅在实时数据库中可用。
此字段仅用于实时数据库触发器和 可调用函数。对于未经身份验证的用户,此字段为null。 对于Firebase管理员用户和不提供用户的事件类型 信息,该字段不存在。
我个人意识到我的数据路径中已经有userId。
export const onCreate = functions.firestore.document('docs/{userId}/docs/{docId}')
.onCreate((snapshot, context) => {
const userId = context.params.userId;
答案 4 :(得分:0)
关于snap._fieldsProto.uid.stringValue
示例:
exports.hello = functions.firestore.document('hello/{worldId}').onCreate((snap, context) => {
console.log(snap._fieldsProto.uid.stringValue)
});
答案 5 :(得分:0)
我如何解决此问题/可行的解决方案的摘要:
在客户端上
将登录的/当前用户的uid(例如,creatorId
)添加到他们正在创建的实体中。通过将firebase.auth().onAuthStateChanged()
用户对象存储在您的应用状态中来访问此uid。
在Firebase Firestore /数据库中
向create
添加一个安全规则,以验证客户端提供的creatorId
值是否与经过身份验证的用户的uid相同;现在您知道客户端没有在欺骗creatorId
,并且可以在其他地方信任此值。
例如
match /entity/{entityId} {
allow create: if madeBySelf();
}
function madeBySelf() {
return request.auth.uid == request.resource.data.creatorId;
}
在Firebase功能中
向您创建的实体类型添加onCreate
触发器,以使用客户端提供的,现已验证的creatorId
来查找创建用户的个人资料信息,并将该信息关联/附加到新的实体文件
这可以通过以下方式完成:
在创建新帐户时创建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)
})
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 })
})
这显然会导致整个系统中出现大量重复的用户信息数据-并且您可以做一些清理工作(在上面的实现中,'creatorId'在创建的实体上是重复的)-但现在超级好了易于显示谁在您的整个应用程序中创建了东西,并且似乎是“ Firebase方式”。
希望这会有所帮助。我发现Firebase在某些方面非常出色,并且使一些通常容易的事情(像这样)比他们“应该”变得更难。总的来说,尽管我是一个主要的粉丝。
答案 6 :(得分:0)
这应该可以解决问题:
exports.newMessage = functions.firestore
.document('groups/messages/{messageId}')
.onCreate((snap, context) => {
var fromId = snap.data().fromId;
答案 7 :(得分:0)
exports.f1 = functions.firestore
.document('collectionname/{id}')
.onCreate ((snap, context) => {
const uid = snap.id;
...
exports.f2 = functions.firestore
.document('collectionname/{id}')
.onUpdate ((change, context) => {
const uid = change.after.id;
...
答案 8 :(得分:0)
您可以通过Callable函数添加数据,从中可以访问当前用户ID:
exports.addNewOffer = functions.https.onCall(async (data, context) => {
const uid = context.auth.uid
const writeResult = await admin.firestore().collection('offers').add({ ... })
...
return { id: writeResult.id, ... }
})
答案 9 :(得分:-1)
您可以通过在用户上调用getIdToken()来获取当前的登录用户tokenId:https://firebase.google.com/docs/reference/functions/functions.auth.UserInfo