web-dev-qa-db-ja.com

Firestore-クラウド関数-uidを取得

クラウド機能で、firebase websdkによって認証されたユーザーのUIDを取得しようとしています。クラウド機能は、クラウドファイヤーストアのonWriteイベントによってトリガーされます。

この機能は、ログインしたユーザーがカフェにアイテムを作成/更新しているときにトリガーされます。認証は_Firebase Auth_によって処理されます。セキュリティルールは、ログインしたユーザーに対してのみ書き込みを有効にします。したがって、このイベントはユーザーに関連付けられる可能性があります。

_export const cfun = functions.firestore.document('cafes/{cafeId}/items/{itemId}').onWrite(async event => {
  // trying to get the uid here
})
_

userIdを扱うドキュメントの例がありますが、これらすべての場合、userIdはドキュメントパスの一部です。ただし、このモデルでは、カフェに複数の所有者がいる可能性があり、多くのユーザーが操作できるため、ユーザーはパスの一部ではありません。したがって、パスにuserIdを追加することはオプションではありません。

サーバーレスアーキテクチャの一般的なケースのように見えます。

更新:firestoreによってトリガーされた関数には、_event.auth_が入力されていません。次の要件のモデル化に関する提案を探しています。

データモデルには、カフェとオーナーがいます。各カフェは多くの所有者によって所有され、カフェは後の段階で他の所有者に譲渡される可能性があります。したがって、カフェは_/cafes/{cafeId}_としてモデル化され、カフェに属するすべてのものは_/cafes/{cafeId}/items/{itemId}_などとしてモデル化されます。ユーザーの下でモデル化すると、さまざまなパラメーターに基づいてカフェをクエリする必要があります。これらの理由により、カフェは_/users/{userId}/cafes/{cafeId}_としてモデル化できません。

セキュリティルールに関する限り、get(<>)を使用して書き込みアクセスを制御し、誰がカフェへの書き込みアクセスを取得するかを決定できます。セキュリティに問題はありません。

実行コンテキストは、利用可能なすべての情報を提供し、開発者がユースケースに適切に処理できるようにする必要があると思います。また、サーバーレスアプリの場合、userIdは必須です。

関数に_event.auth_が指定されていない場合、この制限により、クラウド関数のuserIdにアクセスするためだけに、ユーザーに属していないアイテムが_/users/{userId}/<item_name>/{itemId}_でモデル化されます。これは自然なことではありません。

また、現時点では、コンソールで実行された変更が原因でクラウド機能がトリガーされたかどうかを判断する方法はありません。 Firebaseデータベースでトリガーされる関数で利用できる_event.auth_情報は、すべてのケースを処理するのに最適です。

このケースを改造する方法に関する提案も歓迎します。

前もって感謝します、

10
sowdri

Cloud Functions 1.0以降、次のようなUIDを取得できます

exports.dbCreate = functions.database.ref('/path').onCreate((snap, context) => {
  const uid = context.auth.uid;
  const authVar = context.auth; 
});

CF1.0のすべての変更に関するFBチームからの素敵な投稿は次のとおりです。 https://firebase.google.com/docs/functions/beta-v1-diff#event_parameter_split_into_data_and_context

context.authのデータはここにあります: https://firebase.google.com/docs/firestore/reference/security/#properties

私も同様の問題に直面しています。 Firebaseでは、簡単でした。event.authからデータを取得するだけでした。これは、Firestoreのベータ段階にある間はまだ実装されていない機能にすぎないと思います。パスへのユーザーIDの追加は、更新を行うユーザーに応じて絶えず変更されるため、前述のようには機能しません。

私のシナリオは、更新されるオブジェクトに「lastUpdatedBy」フィールドを作成したいというものです。クライアントがペイロードのlastUpdatedByフィールドを送信することを許可した場合、これは、他の誰かになりすまそうとする不正なクライアント(つまり、認証されたアカウントを持つ誰か)によって悪用される可能性があります。そのため、Firebaseでは、クラウド関数を使用して、データ変更イベントでこのフィールドにデータを入力しました。

私の回避策は、クライアントが「lastUpdatedBy」フィールドを挿入できるようにすることですが、さらにFirestoreルールを使用して、ペイロードのuserIdがログインユーザーのuserIdと一致することを検証します。それ以外の場合は書き込み要求を拒否します。

何かのようなもの:

match /collectionA/{docId} {
  allow update: if request.resource.data.lastUpdatedBy == request.auth.uid;
}

Google/Firestoreの担当者が「auth」オブジェクトをクラウド機能に追加するまで、他の回避策は見当たりませんが、別の方法で聞きたいと思います。

12
Chris