web-dev-qa-db-ja.com

パブリックフィールドとプライベートフィールドのFirestoreセキュリティルール

Firebase Realtime Databaseのセキュリティルールについては、次のルールなどを使用して、パブリックデータとプライベートデータの両方を同じツリーに含めることができます。

ただし、Firestoreを使用する場合、取得できるデータの集まりはコレクションまたはドキュメントの下にあるため、同じことを行うことができないようです。パブリックデータとプライベートデータが同じドキュメントで定義されており、コレクション/ドキュメントでデータを取得すると、所有者でない場合、プライベートデータと同様に権限が不足するというエラーが発生します。

RTDBを使用する場合、コレクション/ドキュメントの概念がないため、「users/{userId}/publicInfo」のデータを取得できます。

FirestoreでRTDBのこれを行う方法はありますか?それ以外の場合は、パブリック/プライベートコレクションを個別に用意する必要がありますか?

// rule of Firebase Realtime Database
"users": {
   "$user_id": {
       ".read": "auth.uid === $user_id",
       ".write": "auth.uid === $user_id",

       "private": {
          ".read": "auth.uid === $user_id"   // --- private data
       }

       "public": {
          ".read": "auth !== null";           // --- public data 
       }
   }
}

// Firestore
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {

      match /{private=**} {
        allow read, write: if request.auth == userId;
      }

      match /{public=**} {
        allow read, write: if request.auth != null;
      }
    }
  }
}
12
miz-k

したがって、ドキュメントの個別の部分に個別のセキュリティルールを設定することはできません。ドキュメント全体を読むことも、読むこともできません。

つまり、ユーザーIDドキュメントに、パブリックおよびプライベートのドキュメントを含む「パブリック」および「プライベート」サブコレクションを提供したい場合、これは完全に実行できることであり、現在セキュリティルールを設定した方法とは異なります。 。

あなたが書いたmatch /{private=**}ビットは、「「プライベート」と呼ばれるサブコレクションと一致する」という意味ではありません。これは、「何であれ、すべてのサブコレクションを照合し、privateという変数に割り当てる」ことを意味します。ドキュメントの「 ワイルドカードを使用した再帰的マッチング 」セクションで、これについて詳しく説明しています。

また、ユーザーのIDを取得するには、request.auth.uidを参照する必要があります。

したがって、おそらく次のようなものが必要です。

// Firestore
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      // You'll probably want to add security rules around the user document 
      // itself. For now, though, let's look at our subcollections:

      match /private/{anything=**} {
        // Only the user can read documents in their private collection
        allow read, write: if request.auth.uid == userId;
      }

      match /public/{anything=**} {
        // Anybody can read documents here, as long as they're signed in
        allow read, write: if request.auth != null;
      }
    }
  }
}
18
Todd Kerpelman