[英]Get current user id from Cloud Functions for Firebase ( PubSub trigger)
[英]Getting the user id from a Firestore Trigger in Cloud Functions for Firebase?
在下面的示例中,有沒有辦法獲取寫入“offers/{offerId}”的用戶的用戶 ID (uid)? 我嘗試按照此處所述進行操作,但在 Firestore 中不起作用。
exports.onNewOffer = functions.firestore
.document('offers/{offerId}')
.onCreate(event => {
...
});
我為此苦苦掙扎了一段時間,最后聯系了 firebase 支持:
event.auth.uid
在event.auth.uid
數據庫觸發器的事件對象中未定義。 (它適用於實時數據庫觸發器)
當我使用console.log(event)
我在輸出中找不到任何auth
。
官方支持答案:
抱歉,Firestore SDK 中尚未添加身份驗證。 我們在接下來的功能中列出了它。
請留意我們的發行說明以獲取任何進一步的更新。
我希望這可以為某人節省幾個小時。
更新:
該問題已關閉,該功能將永遠不會實現:
大家好 - 另一個更新。 遺憾的是,由於技術限制,Firestore 觸發器的 context.auth 的本機支持將不會實現。 但是,工作中有一個不同的解決方案,希望能滿足您的用例,但我不能分享細節。 在這個論壇上,我們通常只保留可以在函數 SDK 本身內部解決的問題 - 我一直保持這個開放,因為它看起來很重要,我想提供一些關於跟蹤這項工作的內部錯誤的更新。 既然已經做出決定,我將關閉它。 再次感謝大家的耐心等待,很抱歉我沒有更好的消息。 請使用此處引用的解決方法。
我如何解決這個問題的總結/一個可行的解決方案:
在客戶端
將登錄/當前用戶的 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
文檔,並使用應用程序有用的字段(例如displayName
)填充新user
文檔。 這是必需的,因為 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 在某些方面非常出色,並且讓一些通常簡單的事情(比如這樣)變得比它們“應該”更難; 總的來說,雖然我是一個大粉絲。
在將其添加到 firestore 函數之前,解決方法是在創建文檔時將user_id
添加為字段,然后刪除。 然后,您可以在 onCreate 函數中獲取它,然后在將其用於您需要的用途之后,在該函數中,只需從該文檔中刪除該字段即可。
文檔明確指出context.auth
參數僅在實時數據庫中可用。
此字段僅為實時數據庫觸發器和可調用函數填充。 對於未經身份驗證的用戶,此字段為空。 對於不提供用戶信息的 Firebase 管理員用戶和事件類型,此字段不存在。
我個人意識到我的數據路徑中已經有了 userId。
export const onCreate = functions.firestore.document('docs/{userId}/docs/{docId}')
.onCreate((snapshot, context) => {
const userId = context.params.userId;
正如上面已經建議的,解決方法是添加一個包含數據本身的 user_id 字段,然后在服務器上讀取它。
這種方法的缺點是存在安全漏洞。 由於我們沒有在服務器上驗證用戶 ID,因此任何其他用戶都可以通過發送其 ID 和數據來冒充其他用戶。
對於安全關鍵的應用程序,解決方案是使用安全規則來驗證正確的 user_id 是否已與數據一起發送
allow write: if resource.data.user_id == request.auth.uid;
snap._fieldsProto.uid.stringValue
是什么
例子:
exports.hello = functions.firestore.document('hello/{worldId}').onCreate((snap, context) => {
console.log(snap._fieldsProto.uid.stringValue)
});
這應該可以解決問題:
exports.newMessage = functions.firestore
.document('groups/messages/{messageId}')
.onCreate((snap, context) => {
var fromId = snap.data().fromId;
您可以通過 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, ... }
})
您可以通過在用戶上調用 getIdToken() 來獲取當前登錄的用戶 tokenId: https ://firebase.google.com/docs/reference/functions/functions.auth.UserInfo
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.