Home > Net >  firestore search query for sub-map [in JavaScript]
firestore search query for sub-map [in JavaScript]

Time:10-25

how to search a document where members map contains a particular map_id

chatRoom: {
MVyMPi78DOwVQ5w5GnYe: {
      ...
      members: {
         <member_1_id>: {
            id: xxxxx,
            unreadmessagecount: xx
         },
         <member_2_id>: {
            id: xxxxx,
            unreadmessagecount: xx
         }
     },
La234Pi78DOwVQ5w5GnYe: {
      ...
      members: {
         <member_1_id>: {
            id: xxxxx,
            unreadmessagecount: xx
         },
         <member_2_id>: {
            id: xxxxx,
            unreadmessagecount: xx
         }
       }
}

like for above structure get all chatrooms where members map contains member_id assume member_id is known enter image description here

CodePudding user response:

You can use dot notation to query documents based on nested field as shown below:

const q = query(collection(db, 'chatRoom'), where('members.user1', '==', {<obj>}))

This won't work for your use-case unless you know the exact object i.e. { uid: 'user1', unreadMessageCount: 1 }.

As a workaround, you can use orderBy() clause that'll only return documents where the field exists like this:

const q = query(collection(db, 'chatRoom'), orderBy('members.user1'))

However, this is actually querying the whole collection and so writing security rules will be a bit difficult. For example, if you use allow read: if request.auth.uid in resource.data.members, the rule will fail as there will be many documents where this returns false.


I would recommend using storing all members' UIDs in an array as follows:

{
  ...
  group: false,
  memberIds: ['user_1_uid', 'user_3_uid']
}

Then you can use array-contains operator to query all chat rooms of a user like this:

const q = query(collection(db, 'chatRoom'), where('memberIds', 'array-contains', 'some_uid'))

Then you can use the following security rules to ensure only a chat member can read/write the document:

allow read, write: if request.auth.uid in resource.data.memberIds
  • Related