简体   繁体   中英

Is there a way to use the where() function and "array-contains" when querying data in firestore and iterate through an array

learning about firestore and making a simple event website to practice search queries where users can enter their city (selectedCity) and then select an event category such as "Music", "Comedy", "Bars" to filter the events.

I have an events array that is dynamic. Users can click on the event types on the side of the screen and it populates the events array depending on which categories are selected. Ex: If I have selected to filter "Music", "Comedy", & "Bars", then the events array would contain those 3.

I was wondering if there was a way to iterate through the array to see if the category of the posted event stored in FireStore matches any of the events in the events array.

Any tips on how to solve this problem would be helpful. Right now I am just hardcoding events[0] which as "Music" in it to display all the music events

Here is my code for the query:

    const [postsList, setPostsList] = useState([])
    const [value, setValue] = useState("");
    const [selectedCity, setSelectedCity] = useRecoilState(selectedCityState);
    const dbRef = collection(db, "posts");

    const [events, setEvents] = useState([
        "Music",
        "Comedy", 
        "Bars", 
      ])


const getPostsAPI = async () => {
        const data = [];
        const q = query(
                dbRef, 
                where("cityName", "==", selectedCity), 
                where("category", "array-contains", events[0]),
                orderBy("timestamp", "desc"));
        const posts = await onSnapshot(q, (querySnapshot) => {
             querySnapshot.docs.map(d => d.data().length)
            querySnapshot.forEach(doc => {
                data.push(
                    { 
                        companyName: doc.data().companyName,
                        endTime: doc.data().endTime,
                        eventAddress: doc.data().eventAddress,
                        eventDescription: doc.data().eventDescription,
                        startTime: doc.data().startTime,
                        startDay: doc.data().startDay,
                        timestamp: doc.data().timestamp,
                        username: doc.data().username,
                        venueName: doc.data().venueName,
                        imageLink: doc.data().imageLink,
                        startMonth: doc.data().startMonth,
                        startDate: doc.data().startDate,
                        title: doc.data().title,
                        cityName: doc.data().cityName,
                        videoLink: doc.data().videoLink,
                    })
            })
            setPostsList(data);
        }, (error) => {
            console.log(`PostAPI error: ${error}`)
        });
    }

I tried passing in the array as a whole thinking the function might compare the two but was incorrect. Trying to figure out the best way to solve this problem and if I have to restructure my code. I know you can only have up to 10 where()'s but I don't think Ill need to do that, nor do I think that would be the most efficient solution.

It sounds like you're looking for array-contains-any from the array query operators :

query(
  dbRef, 
  where("cityName", "==", selectedCity), 
  where("category", "array-contains-any", events), // 👈
  orderBy("timestamp", "desc")
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM