私の目的:
Webアプリ(Googleドライブに類似)には2つの画面があります。
最初の画面は「マイストーリー」で、私が所有者であるすべてのストーリードキュメントが表示されます。
2番目の画面は「私と共有」です。ここには、私が読者、ライター、またはコメンターであるすべてのストーリードキュメントが表示されます。
これがあります/ stories/{storyid}
{
title: "A Great Story",
content: "Once upon a time ...",
roles: {
alice: "owner",
bob: "reader",
david: "writer",
jane: "commenter"
// ...
}
}
完全なデータ構造のリファレンス: https://firebase.google.com/docs/firestore/solutions/role-based-access
質問:上記の目的を満たすために、以下のクエリをどのように記述しますか?
db
.collection('stories')
.where(`roles.${uid}`, '==', 'owner')
上記のクエリは、roles.alice、roles.bob、roles.david、roles.jane、roles。[all_uid]。
編集#1:関連する投稿が見つかりました(回答なし) Firestore querying with roles
ユーザーごとに個別にインデックスを作成する必要がない方法で、実際のデータベース構造でこれを実現することはできません。これを解決するには、データを複製する必要があります。このプラクティスはdenormalization
と呼ばれ、Firebaseに関しては一般的なプラクティスです。 NoQSLデータベースを初めて使用する場合は、このビデオをご覧になることをお勧めします 非正規化はFirebaseデータベースでは正常です 理解を深めるため。これはFirebaseリアルタイムデータベース用ですが、Cloud Firestoreにも同じルールが適用されます。
また、データを複製する場合は、留意すべきことが1つあります。データを追加するのと同じ方法で、データを維持する必要があります。つまり、アイテムを更新/削除する場合は、存在するすべての場所で行う必要があります。
つまり、userStories
という名前の別のコレクションを作成する必要があります。この場合、ユーザーがowner
であるすべてのストーリーをドキュメントとして追加する必要があります。したがって、データベース構造は次のようになります。
Firestore-root
|
--- userStories (collection)
|
--- uid (document)
|
--- allStories (collection)
|
--- storyId
|
--- role: "owner"
したがって、次のようなクエリ:
db.collection('userStories').doc(${uid})
.collection('allStories').where(`role`, '==', 'owner');
完全に正常に動作します。
したがって、NoSQLでデータを複製する必要はありません。
考えられるデータ構造の1つは
/ stories/{storyid}
{
title: "A Great Story",
content: "Once upon a time ...",
roles: {
alice: "owner",
bob: "reader",
david: "writer",
jane: "commenter",
mary: "writer",
// ...
},
owner: "alice", // newly added
shared: ["bob", "david", "jane", "mary"] // newly added
// alice, bob, david, jane, mary are firebase auth uid
}
これで、WebアプリのUI「My Story」をクエリできます
db
.collection('stories')
.where('owner', '==', uid)
「Shared with me」のWebアプリUIをクエリできますが
db
.collection('stories')
.where('shared', 'array_contains', uid)
回答は、@ Doug Stevensonのコメントに触発されています。