以下の例では、「offers/{offerId}」に書き込んだユーザーのユーザーID(uid)を取得する方法はありますか? ここ のようにしてみましたが、Firestoreでは機能しません。
exports.onNewOffer = functions.firestore
.document('offers/{offerId}')
.onCreate(event => {
...
});
私がこれを解決した方法の要約/実行可能なソリューション:
クライアント上
ログイン/現在のユーザーのuid(例:creatorId
)を、作成中のエンティティに追加します。このuidにアクセスするには、firebase.auth().onAuthStateChanged()
ユーザーオブジェクトをアプリの状態で保存します。
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 Authenticationシステムによって公開されたフィールドがコンシューマーアプリで使用するには不十分であるため(たとえば、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
トリガーを追加して、作成中のユーザーのinfoを作成したオブジェクトに追加します。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でそれを取得し、それを必要な目的に使用した後、関数内でそのドキュメントからフィールドを削除します。
すでに上記で提案されているように、回避策は、データ自体を含むuser_idフィールドを追加し、サーバーでそれを読み取ることです。
このアプローチの欠点は、セキュリティの抜け穴になることです。サーバーでユーザーIDを確認していないため、他のユーザーは、IDをデータと共に送信することにより、他のユーザーになりすますことができます。
セキュリティが重要なアプリケーションの場合、解決策は、セキュリティルールを使用して、正しいuser_idがデータとともに送信されたことを確認することです。
allow write: if resource.data.user_id == request.auth.uid;
これでうまくいくはずです:
exports.newMessage = functions.firestore
.document('groups/messages/{messageId}')
.onCreate((snap, context) => {
var fromId = snap.data().fromId;
snap._fieldsProto.uid.stringValue
について
例:
exports.hello = functions.firestore.document('hello/{worldId}').onCreate((snap, context) => {
console.log(snap._fieldsProto.uid.stringValue)
});