Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore: How to query a map object inside a collection of documents?

My objective:

The web app (similar to Google Drive) has 2 screens.

First screen is 'My Story' which displays all the story documents whom I'm the owner.

Second screen is 'Shared with me' which displays all the story documents that I'm either reader, writer, or commenter.

We have this /stories/{storyid}

{
  title: "A Great Story",
  content: "Once upon a time ...",
  roles: {
    alice: "owner",
    bob: "reader",
    david: "writer",
    jane: "commenter"
    // ...
  }
}

Full data structure reference: https://firebase.google.com/docs/firestore/solutions/role-based-access

Question: How to write the below query to fulfil the above objective?

db
.collection('stories')
.where(`roles.${uid}`, '==', 'owner')

The above query does NOT work because it will require Firestore to index roles.alice, roles.bob, roles.david, roles.jane, and roles.[all_uid].


Edit #1: Found a related post (with no answers) asking about Firestore querying with roles

like image 266
Jek Avatar asked Feb 21 '19 16:02

Jek


People also ask

How does Cloud Firestore retrieve data from a collection?

By default, Cloud Firestore retrieves all documents that satisfy the query in ascending order by document ID, but you can order and limit the data returned. In addition, you can retrieve all documents in a collection by omitting the where () filter entirely:

Why does the above query not work in FireStore?

The above query does NOT work because it will require Firestore to index roles.alice, roles.bob, roles.david, roles.jane, and roles. [all_uid]. Edit #1: Found a related post (with no answers) asking about Firestore querying with roles

What happens when I set a listener in Cloud Firestore?

When you set a listener, Cloud Firestore sends your listener an initial snapshot of the data, and then another snapshot each time the document changes. Note: While the code samples cover multiple languages, the text explaining the samples refers to the Web method names.

How to update/detele items in a story?

With other words, if you want to update/detele an item, you need to do it in every place that it exists. That being said, you should create another collection named userStories, where you should add as documents all stories where a user is owner.


2 Answers

Now you can filter ...

db
  .collection('orders')
  .where('orderDetails.status', '==', 'OPEN')

It will check if field orderDetails at property status equals to 'OPEN'

like image 106
Cristi Maris Avatar answered Oct 29 '22 14:10

Cristi Maris


enter image description herePlease let me know if I'm mistaken, but it appears that your query should actually work. as an experiment I added the structure you gave in the question and performed the query successfully in the firebase console.

Is this not what you are going for? I also made sure that the "in" operator works for this case as well. In this way you could ask which stories the user is owner & commenter.

enter image description here

This pulls in the correct results: enter image description here

like image 29
Grahambo Avatar answered Oct 29 '22 14:10

Grahambo