0

I want to have a user select several sports teams from an NHL list or more specifically firebase to act like tags.

In a document I want to include an array that might have the tags of a story, #leafs, #senators #nhl.

Now I want to have the user interested in say #leafs #canadiens #nhl #ohl

I plan on storing the two in an array,

in Flutter

interestArray = ["leafs","canadiens",nhl,"ohl"] 

So how do I,

get from Firebase interestArray from the array field "storyTags"?

  .where('storyTags', arrayContains: interestArray )

Is this supposed to work?

3
  • If I get you right, that should work. I once had a project with few friends and we did the same thing, that we stored our tags in an array that was in a users document. Commented Aug 27, 2019 at 18:13
  • I'm not sure if arrayContains can take an array as a parameter, I believe it takes only single strings. That's how I use it on my case though. Commented Aug 28, 2019 at 1:10
  • How do you compare multiple tags to multiple tags and get a query return. Commented Aug 28, 2019 at 16:18

2 Answers 2

1

Unfortunately, 'arrayContains' can only take a single value, rather than an array. So you could test .where('storyTags', arrayContains: 'leafs') but not 'leafs', 'canadiens'

However, a similar question has been asked before: Firestore search array contains for multiple values. (tl;dr: Use a map.)

Adapting that solution might result in a schema like:

Stories:
  <docid>:
    title: "Leafs to play Canadiens"
    tags: {
      "leafs": true,
      "canadiens": true,
      "nhl": true
    }

And then to query it for all stories involving both the leafs and the canadiens, you'd use something like:

db.collection("Stories")
  .where("tags.leafs", "==", true)
  .where("tags.canadiens", "==", true);

(Note that Firestore does not support logical 'OR' queries; to do that, you'd need to issue separate queries and then merge the results. https://firebase.google.com/docs/firestore/query-data/queries#query_limitations)

Update in response to comment:

As mentioned above, it's unfortunately not possible to perform a logical 'OR' query. So to fetch all stories tagged with either team, you'd need to do something like this (in javascript):

var leafsSnapshot = await db.collection("Stories").where("tags.leafs", "==", true).get();
var habsSnapshot = await db.collection("Stories").where("tags.canadiens", "==", true).get();

// Concatenate the results together and log the story titles.
var stories = leafsSnapshot.docs.concat(habsSnapshot.docs);

// This won't quite work:
//
//     stories.forEach(story => console.log(story.get("title")));
//
// It won't de-duplicate stories, so any story that's tagged with *both*
// will be printed twice.

var seen = new Set([])
stories.forEach(story => {
  if (!seen.has(story.id)) {
    seen.add(story.id);
    console.log(story.get("title"));
  }
});

Alternatively, if you're not interested in 'AND' queries, you could go back to using arrayContains and follow a similar approach as above. i.e.:

var leafsSnapshot = await db.collection("Stories").where("storyTags", "arrayContains", "leafs").get();

// the rest is the same.
Sign up to request clarification or add additional context in comments.

1 Comment

I am not looking for a solution where the game contains both the leafs and the Canadiens, I am looking for a solution where it contains Either team not Both. I want to query all stories involving the leafs OR the canadiens Does the sample code work for or?
0

We recently announced that Cloud Firestore supports two new kinds of queries: "in" and "array-contains-any". They let you find documents with any of several values (up to 10).

That might help!

Comments

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.