0

I used to have a document with the following structure:

OldDoc:

members: ['userId1', 'userId2', 'userId3']

I then wrote a query to retrieve all documents relevant to a user:

const docsSnapshot = await getDocs(query(
    collection(db, 'organisations'),
    where('members', 'array-contains', user.uid)
))

This worked well, but now I need to store the user's names in as well as:

members: [{ id: 'userId1', name: 'John Smith' }, { id: 'userId2', name: 'Jane Smith' }]

The challenge I'm facing is that I'm not sure how to construct a query that would yield the same results as the first one - i.e., how do I retrieve all docs where any of the objects have an id attribute corresponding to user.uid.

I tried using: where('members.id', '==', user.uid) but that didn't work.

Can a query be constructed to do this?

3
  • See stackoverflow.com/questions/54081799/… Commented May 9, 2022 at 9:10
  • if you add all members in the same doc is going to be hard later, you need to do a document for each memeber, even if they hold 2 values, and add the doc name their uid as setDoc(doc(db, "organisations", uid), {name: ...., uid:...}) or make a subcollection setDoc(doc(db, "organsiations", "members", "subcollection", uid), {.....data...}) Commented May 9, 2022 at 9:17
  • I'm trying to avoid creating a doc for each member because I'm building a page which displays all members of an organisation, and I don't want to incur cost of a read for each member in an org every time an org is displayed. Commented May 9, 2022 at 9:47

1 Answer 1

1

Firestore isn't great at these kinds of queries... I'd consider restructuring your member array to be an object with user.id as keys.

members : {
   userId1: { name: "fred" },
   userId2: { name: "martha" }
}

Another way, and perhaps more closely aligned to how Firestore 'wants' you to do it, would be to create another subcollection members with a new document for each member with the doc.id set to the user.id.

This approach also allows you to easily add more data to each member, with the added benefit of making queries on members that don't just rely on the user.id.

Sign up to request clarification or add additional context in comments.

3 Comments

I'm trying to avoid the second approach as to not incur read cost for every individual user when I'm trying to get a list of users with basic info. The first approach of restructuring the data looks promising though. How would I write a query to check if user.uid exists as an object key in the members object? I tried where(members.${user.uid}, '!=', null) but that returns always returns all documents. where('members', 'in', user.uid) display any.
On phone, so tricky editing but collection.orderBy(members.userId1) should do the trick I think?
I was actually wrong. where(``members.${user.uid}``, '!=', null) works perfectly fine. Thanks for your help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.