簡體   English   中英

從 Cloud Functions for Firebase 中的 Firestore 觸發器獲取用戶 ID?

[英]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.uidevent.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來查找創建用戶的個人資料信息,並將此信息關聯/附加到新實體文檔。

這可以通過以下方式實現:

  1. 創建新帳戶時創建users集合和個人user文檔,並使用應用程序有用的字段(例如displayName )填充新user文檔。 這是必需的,因為 Firebase 身份驗證系統公開的字段不足以供消費者應用程序使用(例如, displayNameavatarURL未公開),因此您不能僅僅依賴於以這種方式查找創建用戶的信息。

    例如(使用 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)
  })
  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 })
})

這顯然會導致整個系統中出現大量重復的用戶信息數據——您可以做一些清理工作(在上述實現中創建的實體上重復了“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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM